【问题标题】:Letting the compiler know that a Generic has a field让编译器知道 Generic 有一个字段
【发布时间】:2014-01-21 07:59:13
【问题描述】:

假设我将有一个名为 getCountry 的通用类型方法:

public T GetCountry<T>(int portalID)
{
    T theCountry = (T)Activator.CreateInstance(typeof(T));
    theCountry.id = "AR";
    if(portalID == 1) theCountry.id = "ARG";
    return theCountry;
}

当然这样不行,因为编译器不知道T里面有一个叫“id”的字段。

我不能做替代解决方案,比如放置 where T extends AbstractCountry 或其他什么,因为这些国家/地区类是顶级类,我无权访问代码来为它们创建父级。代码不是我的(不幸的是设计得很糟糕)。这意味着我也无法为不同的国家/地区类型创建构造函数并使用 Activator 类将 id 作为参数发送,而我个人对泛型的了解就到此为止了。

有什么方法可以实现我想要做的事情吗?谢谢大家!!!

【问题讨论】:

    标签: c# .net


    【解决方案1】:

    在创建实例时使用dynamic,这允许您在其上使用任意成员(“后期绑定”)。如果T 没有具有该名称的属性或字段,则会引发运行时错误。

    在返回之前将对象转换回T

    public T GetCountry<T>(int portalID)
    {
        dynamic theCountry = Activator.CreateInstance(typeof(T));
        theCountry.id = "AR";
        if(portalID == 1) theCountry.id = "ARG";
        return (T)theCountry;
    }
    

    【讨论】:

    • 是的,当你说你的 PS 时,我已经编辑了帖子。那真是太快了。谢谢!!!
    【解决方案2】:

    是的,在 C# 中使用 dynamic featureas explained here

    【讨论】:

      【解决方案3】:

      dynamic 功能相反,您可以使用通用参数约束

      public interface IIdentifier
      {
          string Id { get; set; }
      }
      
      public static T GetCountry<T>(int portalID) where T : IIdentifier
      {
          T theCountry = (T)Activator.CreateInstance(typeof(T));
          theCountry.Id = "AR";
          if (portalID == 1) theCountry.Id = "ARG";
          return theCountry;
      }
      

      IIdentifier 可以是一些具有您需要的所有属性的基本类型。如果没有通用的基本类型,那么dynamic 就是要走的路。

      值得注意的是,当您将 dynamic 与没有名为 Id 的成员的类型一起使用时,这将在运行时失败,但是当您使用泛型约束时,您将无法编译它,这将是好的而不是默默地失败运行时。

      【讨论】:

      • 是的,没有通用接口或我在问题中所说的任何东西。我也无法编辑它们。真可惜=(。谢谢!
      • @Damieh 如果没有通用的基本类型,则使用dynamic。请务必阅读我的编辑。
      猜你喜欢
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多