获取泛型类型的实例

时间:2014-08-22 01:42:25

标签: c# generics

我有2个Customer类BusinessCustomer和NormalCustomer具有单独的属性和验证方法。从实现类,基于某些条件,我可能会创建Customer1或Customer2。 如何基于Customer类中的T创建BusinessCustomer或NormalCustomer的实例,以便我可以调用两个类共有的validate方法。

    public class Customer<T> where T : class
    {
        public T CustomerType;
        bool isValid;

        public Customer() //constructor
        {
            //for customer1, i want a new instance of BusinessCustomer 
            //for customer2, i want a new instance of NormalCustomer 
        }

        public bool Validate()
        {
            isValid = CustomerType.Validate();
        }
    }


public class BusinessCustomer
{
    public string CustomerHobby { get; set; }
    public bool Validate()
    {
        return true;
    }
}

public class NormalCustomer
{
    public string CustomerEducation { get; set; }
    public bool Validate()
    {
        return false;
    }
}

public class Implement
{
    public void ImplementCustomer()
    {
        var customer1 = new Customer<BusinessCustomer>();
        customer1.CustomerType = new BusinessCustomer {CustomerHobby="Singing"};
        customer1.Validate();

        var customer2 = new Customer<NormalCustomer>();
        customer2.CustomerType = new NormalCustomer { CustomerEducation = "High School" };
        customer2.Validate();

    }
}

1 个答案:

答案 0 :(得分:2)

您的第一个问题是以下一行:

isValid = CustomerType.Validate();

由于CustomerType的类型为T,可以是任何类,因此编译器无法保证可以调用Validate()方法。您需要通过创建一个通用接口来解决这个问题。我们称之为ICustomer

interface ICustomer
{
   bool Validate();
}

现在,BusinessCustomerNormalCustomer都需要实现所述接口:

public class BusinessCustomer : ICustomer
{
   // Same code
}

public class NormalCustomer : ICustomer
{
   // Same code
}

接下来,你必须改变:

public class Customer<T> where T : class

要:

public class Customer<T> where T : ICustomer

现在,您只能创建Customer<T> 实施<{em> T的{​​{1}}个实例,这样您就可以调用{{1} } ICustomer的方法。

接下来,如果您想在构造函数中 new up Validate,您可以这样做:

CustomerType

但是等等。如果T没有默认的公共构造函数,或者是抽象的,该怎么办?我们还需要将此约束添加到我们的泛型类型:

public Customer()
{
   CustomerType = new T();
}

现在,T有效,您只能创建public class Customer<T> where T : class, new() 的实例,其中new T();具有默认构造函数。如果您不想,您将不再需要设置Customer<T>

另一个快速说明。你的方法:

T

要么返回 bool(例如customer1.CustomerType),要么签名需要public bool Validate() { isValid = CustomerType.Validate(); } 。现在,您将收到编译器错误,因为并非所有代码路径都返回值。

希望这有帮助!