Создание класса типа ASP.NET MVC 3 ViewBag?


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

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

5 17

5 ответов:

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

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

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

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

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

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

dynamic ViewBag = new System.Dynamic.ExpandoObject();

Я думаю, вам нужен анонимный тип. См. 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);