从扩展方法动态添加新对象 属性

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 中将结果保存为 PropertyCAObject默认没有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 隐藏。如果是这样,您可以更改 PropertyAProprertyB 的 getter 和 setter 以访问 _members 或者您可以在 Try(Get|Set)Member 中处理这种情况。将这些属性添加到 _member 也开启了迭代这些成员的可能性。