从扩展方法动态添加新对象 属性
Adding new object property dynamically from extension method
这是我的方案...我想要一些基础 class 并为此 class 设置一些扩展方法,这些方法可能会托管在不同的程序集中。根据添加到项目中的程序集,应计算不同的属性并将其存储在其中。
我有点基础class
public class AObject
{
public string PropertyA { get; set; }
public int PropertyB { get; set; }
}
并且对此有一些扩展方法class
public static class AObjectExtensions
{
public static void DoSomething(this AObject a, string value)
{
a.PropertyC = value;
}
}
我想得到的是,我想在扩展方法 DoSomething
中进行一些计算,并在 AObject
中将结果保存为 PropertyC
。 AObject
默认没有PropertyC
,想动态添加。我发现要使用动态属性,我必须使用 ExpandoObject
,但不确定我在这里看到如何使用它...
所以,主要问题是这是一个很好的方案还是我必须考虑其他事情?
您需要从 DynamicObject
继承您的对象:
public class AObject : DynamicObject
{
public string PropertyA { get; set; }
public int PropertyB { get; set; }
#region Dynamic Part
private readonly Dictionary<string, object> _members = new Dictionary<string, object>();
public override bool TrySetMember(SetMemberBinder binder, object value)
{
this._members[binder.Name] = value;
return true;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return this._members.TryGetValue(binder.Name, out result) || base.TryGetMember(binder, out result);
}
public override IEnumerable<string> GetDynamicMemberNames()
{
return this._members.Keys;
}
#endregion
}
您的扩展方法必须更改为:
public static class AObjectExtensions
{
public static void DoSomething(this AObject a, string value)
{
((dynamic)a).PropertyC = value;
}
}
您可以使用 GetDynamicMemberNames()
遍历所有动态成员,如果 AObject
提供索引器或访问 this._members
的 getter 方法,您可以访问所有动态值。
编辑:
使用此解决方案可能会出现问题。我没有测试它。 ((dynamic)a).PropertyA
可能会被 Try(Get|Set)Member
隐藏。如果是这样,您可以更改 PropertyA
和 ProprertyB
的 getter 和 setter 以访问 _members
或者您可以在 Try(Get|Set)Member
中处理这种情况。将这些属性添加到 _member
也开启了迭代这些成员的可能性。
这是我的方案...我想要一些基础 class 并为此 class 设置一些扩展方法,这些方法可能会托管在不同的程序集中。根据添加到项目中的程序集,应计算不同的属性并将其存储在其中。
我有点基础class
public class AObject
{
public string PropertyA { get; set; }
public int PropertyB { get; set; }
}
并且对此有一些扩展方法class
public static class AObjectExtensions
{
public static void DoSomething(this AObject a, string value)
{
a.PropertyC = value;
}
}
我想得到的是,我想在扩展方法 DoSomething
中进行一些计算,并在 AObject
中将结果保存为 PropertyC
。 AObject
默认没有PropertyC
,想动态添加。我发现要使用动态属性,我必须使用 ExpandoObject
,但不确定我在这里看到如何使用它...
所以,主要问题是这是一个很好的方案还是我必须考虑其他事情?
您需要从 DynamicObject
继承您的对象:
public class AObject : DynamicObject
{
public string PropertyA { get; set; }
public int PropertyB { get; set; }
#region Dynamic Part
private readonly Dictionary<string, object> _members = new Dictionary<string, object>();
public override bool TrySetMember(SetMemberBinder binder, object value)
{
this._members[binder.Name] = value;
return true;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return this._members.TryGetValue(binder.Name, out result) || base.TryGetMember(binder, out result);
}
public override IEnumerable<string> GetDynamicMemberNames()
{
return this._members.Keys;
}
#endregion
}
您的扩展方法必须更改为:
public static class AObjectExtensions
{
public static void DoSomething(this AObject a, string value)
{
((dynamic)a).PropertyC = value;
}
}
您可以使用 GetDynamicMemberNames()
遍历所有动态成员,如果 AObject
提供索引器或访问 this._members
的 getter 方法,您可以访问所有动态值。
编辑:
使用此解决方案可能会出现问题。我没有测试它。 ((dynamic)a).PropertyA
可能会被 Try(Get|Set)Member
隐藏。如果是这样,您可以更改 PropertyA
和 ProprertyB
的 getter 和 setter 以访问 _members
或者您可以在 Try(Get|Set)Member
中处理这种情况。将这些属性添加到 _member
也开启了迭代这些成员的可能性。