让编译器知道Generic有一个字段

时间:2014-01-03 15:35:11

标签: c# .net

所以,假设我要使用一个名为getCountry的Generic Type方法:

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作为参数发送,并且就此而言,我的泛型知识结束了。

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

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:2)

创建实例时使用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;
}

答案 2 :(得分:2)

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是可行的方法。

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