【问题标题】:Naming a generic property after its type根据类型命名泛型属性
【发布时间】:2013-10-30 19:53:10
【问题描述】:

我有一个这样的 C# 类(为简单起见,删除了额外的属性):

public class MyClass<T>
{
    public T MyProperty { get; set; }
}

是否可以在T 的类型之后以某种方式动态命名MyProperty

例如,如果我将我的类实例化为:

MyClass<MyOtherClass> myClass = new MyClass<MyOtherClass>();

我希望 MyProperty 的名称改为 MyOtherClass。我环顾了 Google 和 StackOverflow,但没有找到类似的东西。这有可能吗?也许使用反射?


编辑:

首先,如果您要否决我的问题,如果您能评论一下原因,我将不胜感激。

其次,也许这有助于澄清我为什么要这样做。此类由 API 返回。它有一些与错误相关的信息,以及表示返回实体的通用类型属性。但是,当进行 API 调用时,响应如下所示:

[
  {
    "MyOtherClass": {
      // properties here
    },
    "Errors": [
      {
        "ErrorCode": 1,
        "Message": "sample string 1"
      },
      {
        "ErrorCode": 1,
        "Message": "sample string 1"
      }
    ]
  }
]

我希望上面的“MyOtherClass”是实体的实际名称(通用类型)。

【问题讨论】:

  • 否;那是完全不可能的。你会如何在课堂上提及它?
  • 你可以(但不应该)使用dynamic
  • 这将完全违背泛型的目的,即在基类中定义基本功能。
  • 感谢您的 cmets。我在我的问题中添加了一些说明。我不确定dynamic 在这种情况下会有什么帮助——我错过了什么吗? (另外,如果使用它不是一个好习惯,那么我不一定想沿着这条路走。)我不是想改变功能,只是改变属性的名称,或者以其他方式找到一种方法来拥有更好地响应我的 API 调用的名称。
  • @SLaks 你可能指的是ExpandoObject,而不是dynamic

标签: c# asp.net generics reflection asp.net-web-api


【解决方案1】:

你可以扩展DynamicObject:

public class MyClass<T> : DynamicObject
{
    private T property;

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        if (binder.Name == typeof(T).Name)
        {
            result = property;
            return true;
        }
        else
        {
            result = null;
            return false;
        }
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        if (binder.Name == typeof(T).Name && value is T)
        {
            property = (T)value;
            return true;
        }
        else
        {
            return false;
        }
    }
}

你可以像这样使用:

dynamic myObj = new MyClass<string>();
myObj.String = "value";

string value = myObj.String;

【讨论】:

  • 谢谢,这正是我正在寻找的答案。然而,经过深思熟虑,我决定为返回的类型设置一个通用名称实际上很好。我决定反对这种方法,因为它会导致我生成的文档出现问题(因为不再有带有公共 getter 的编译时属性)以及 cmets 中提到的一些原因。尽管如此,你还是完美地回答了我所说的我想要的问题,所以我仍然相信它应该成为公认的答案。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-12
相关资源
最近更新 更多