简体   繁体   English

分配给对象的动态属性

[英]Dynamic property assigned to object

Is it possible to attach dynamic property to an object of user-defined class? 是否可以将dynamic属性附加到用户定义的类的对象?

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

    public int NumberOfWindows { get; set; }
}

then from other context: 然后从其他上下文:

Room room = new Room();

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

and then somehow associate NumberOfWalls with room , as its property? 然后以某种方式将 NumberOfWallsroom关联为其属性?

Update (Larger Picture): 更新(大图):

as per @nawfal's suggestion 根据@nawfal的建议

I have a cached List<Room> being iterated in a razor view (outside the themes folder), calling a 我有一个缓存的List<Room>在剃刀视图(主题文件夹外部)中被迭代,调用

particular partial view (from the current theme) for each element. 每个元素的特定局部视图(来自当前主题)。 One of the theme needs an extra 主题之一需要额外

property in Room. 房间里的财产。 I only have access to modify code in that particular theme folder, the partial 我只能修改该特定主题文件夹中的代码,部分

views cshtml files (don't ask why). 查看cshtml文件(不要问为什么)。

So its basically: 所以它基本上是:

(psuedocode) (伪码)

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


I am looking for a way o update the List<Room> rooms object with NoOfWalls in 我正在寻找一种使用NoOfWalls更新List<Room> rooms对象的方法

HttpRuntime.Cache["rooms"] to avoid calling SomeHeavyLiftingProcess() with each request. HttpRuntime.Cache["rooms"]避免对每个请求调用SomeHeavyLiftingProcess() The

goal is to inject a property in cached object. 目标是在缓存的对象中注入属性。 Unfortuntely HttpRuntime.Cache["rooms"] is object 不幸的是HttpRuntime.Cache["rooms"]是对象

type and doesn't allow me to do this: 输入,不允许我这样做:

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

So I am thinking, for the first request (when cache is empty or invalid): 所以我在想,对于第一个请求(当缓存为空或无效时):

  • Unpackig: Retrieve (List<Room>)HttpRuntime.Cache["room"] , inject NoOfWalls in the current room object. 解压缩:检索(List<Room>)HttpRuntime.Cache["room"] ,将NoOfWalls注入当前的Room对象中。

  • Repacking: Update List<Room> room with the new object and assign it back to HttpRuntime.Cache . 重新打包:使用新对象更新List<Room> room ,并将其分配回HttpRuntime.Cache


For the subsequent requests, the value of NoOfWalls will come from cached object @Model.NoOfWalls . 对于后续请求,NoOfWalls的值将来自缓存的对象@Model.NoOfWalls

You cannot add properties not defined in a class to an existing instance, without using a dynamic object like ExpandoObject . 如果不使用ExpandoObject类的动态对象,则无法将类中未定义的属性添加到现有实例中。

If you need to add members to an existing class, you can create a child class with a special constructor: 如果需要将成员添加到现有类,则可以使用特殊的构造函数创建子类:

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

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

    public int NumberOfJacuzzis { get; set; }
}

Usage: 用法:

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

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

Or: 要么:

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

If you have an existing concrete object (like an instance of the Room class), you can convert it to a dynamic object with a method like this: 如果您有一个现有的具体对象(例如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;
}

Usage: 用法:

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

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

Now dynamicObject.NumberOfDoors will be 3, and dynamicObject.WhateverYouWant will be 7. 现在, dynamicObject.NumberOfDoors将为3, dynamicObject.WhateverYouWant将为7。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM