Создание класса, как ASP.NET MVC 3 ViewBag? - PullRequest
17 голосов
/ 27 апреля 2011

У меня есть ситуация, когда я хотел бы сделать что-то похожее на то, что было сделано с объектом ASP.NET MVC 3 ViewBag, где свойства создаются во время выполнения? Или это во время компиляции?

В любом случае, мне было интересно, как создать объект с таким поведением?

Ответы [ 5 ]

23 голосов
/ 10 февраля 2013

Я создал что-то вроде этого:

public class MyBag : DynamicObject
{
    private readonly Dictionary<string, dynamic> _properties = new Dictionary<string, dynamic>( StringComparer.InvariantCultureIgnoreCase );

    public override bool TryGetMember( GetMemberBinder binder, out dynamic result )
    {
        result = this._properties.ContainsKey( binder.Name ) ? this._properties[ binder.Name ] : null;

        return true;
    }

    public override bool TrySetMember( SetMemberBinder binder, dynamic value )
    {
        if( value == null )
        {
            if( _properties.ContainsKey( binder.Name ) )
                _properties.Remove( binder.Name );
        }
        else
            _properties[ binder.Name ] = value;

        return true;
    }
}

, тогда вы можете использовать это так:

dynamic bag = new MyBag();

bag.Apples = 4;
bag.ApplesBrand = "some brand";

MessageBox.Show( string.Format( "Apples: {0}, Brand: {1}, Non-Existing-Key: {2}", bag.Apples, bag.ApplesBrand, bag.JAJA ) );

обратите внимание, что запись для "JAJA" никогда не создавалась ... и до сих порне выдает исключение, просто возвращает null

надеюсь, это кому-нибудь поможет

8 голосов
/ 27 апреля 2011

Поведение ViewBag действует примерно так же, как ExpandoObject , так что, возможно, то, что вы хотите использовать. Тем не менее, если вы хотите использовать пользовательское поведение, вы можете создать подкласс DynamicObject . Ключевое слово dynamic важно при использовании объектов такого типа, поскольку оно указывает компилятору связывать вызовы методов во время выполнения, а не во время компиляции, однако ключевое слово dynamic в простом старом типе clr будет просто избегать проверки типов и не предоставит вашему объекту динамический тип реализации, для которого предназначены ExpandoObject или DynamicObject.

7 голосов
/ 27 апреля 2011

Используйте объект типа dynamic. См. Эту статью для получения дополнительной информации.

5 голосов
/ 09 декабря 2014

ViewBag объявлено так:

dynamic ViewBag = new System.Dynamic.ExpandoObject();
4 голосов
/ 27 апреля 2011

Я думаю, вы хотите анонимный тип. Смотри http://msdn.microsoft.com/en-us/library/bb397696.aspx

Например:

var me = new { Name = "Richard", Occupation = "White hacker" };

Тогда вы можете просто получить свойства, как в обычном C #

Console.WriteLine(me.Name + " is a " + me.Occupation);
...