分配给对象的动态属性

时间:2013-11-20 03:12:39

标签: c# asp.net razor http-caching expandoobject

是否可以将dynamic属性附加到用户定义的类的对象?

public class Room
{
    public int NumberOfDoors { get; set; }

    public int NumberOfWindows { get; set; }
}

然后来自其他背景:

Room room = new Room();

dynamic contact = new ExpandoObject();
contact.NumberOfWalls = 4;

然后以某种方式NumberOfWallsroom关联,作为其属性?

更新(放大图片):

根据@ nawfal的建议

我在剃刀视图中(在主题文件夹之外)迭代了一个缓存的List<Room>,调用了一个

每个元素的特定局部视图(来自当前主题)。其中一个主题需要额外的

房间的财产。我只能访问修改特定主题文件夹中的代码,即部分

查看cshtml文件(不要问为什么)。

所以基本上:

(伪码)

Room.NoOfWalls = SomeHeavyLiftingProcess(Room.NoOfWindows, Room.NoOfDoors)


我正在寻找一种用

中的NoOfWalls更新List<Room> rooms对象的方法

HttpRuntime.Cache["rooms"]以避免在每次请求时调用SomeHeavyLiftingProcess()

目标是在缓存对象中注入属性。不幸的是HttpRuntime.Cache["rooms"]是对象

输入并且不允许我这样做:

HttpRuntime.Cache["rooms"][3]["NoOfWalls"] = SomeHeavyLiftingProcess(..)

所以我想,对于第一个请求(当缓存为空或无效时):

  • Unpackig:检索(List<Room>)HttpRuntime.Cache["room"],在当前房间对象中注入NoOfWalls。

  • 重新包装:使用新对象更新List<Room> room并将其分配回HttpRuntime.Cache


对于后续请求,NoOfWalls的值将来自缓存对象@Model.NoOfWalls

1 个答案:

答案 0 :(得分:1)

如果不使用像ExpandoObject这样的动态对象,则无法将类中未定义的属性添加到现有实例。

如果需要向现有类添加成员,可以使用特殊构造函数创建子类:

public class SpecialRoom : Room
{
    public SpecialRoom() { }

    public SpecialRoom(Room copy)
    {
        this.NumberOfDoors = copy.NumberOfDoors;
        this.NumberOfWindows = copy.NumberOfWindows;
    }

    public int NumberOfJacuzzis { get; set; }
}

用法:

var room = new Room();
room.NumberOfDoors = 3;

var specialRoom = new SpecialRoom(room)
{
    NumberOfJacuzzis = 7
};

或者:

var listOfRooms = new List<Room>();
// ...
var listOfSpecialRooms = listOfRooms.Select(x => new SpecialRoom(x));
listOfSpecialRooms.ForEach(x => x.NumberOfJacuzzis = ComplexCalculation(x));

如果您有一个现有的具体对象(如Room类的实例),您可以使用如下方法将其转换为动态对象:

public static dynamic ConvertObjectToDynamic(object value)
{
    if (value == null)
    {
        return null;
    }

    IDictionary<string, object> dynamicObject = new ExpandoObject();
    var properties = value.GetType().GetProperties(
        BindingFlags.Public | BindingFlags.Instance);

    foreach (var propertyInfo in properties)
    {
        if (propertyInfo.GetIndexParameters().Length == 0)
        {
            var propertyValue = propertyInfo.GetValue(value);
            dynamicObject[propertyInfo.Name] = propertyValue;
        }
    }

    return dynamicObject;
}

用法:

var room = new Room();
room.NumberOfDoors = 3;

dynamic dynamicObject = ConvertToDynamic(room);
dynamicObject.WhateverYouWant = 7;

现在dynamicObject.NumberOfDoors为3,dynamicObject.WhateverYouWant为7。