仿制药可以做什么,你不能用组合做什么?

时间:2015-05-28 07:45:28

标签: c#

给出一个课程:

public class TestMain
{

}

两个类接受这个类的实例,一个通过泛型:

public class Test1<T> where T : TestMain
{
    public Test1(T test)
    {

    }   
}   

一个没有:

public class Test2
{
    public Test2(TestMain test)
    {

    }
}

为什么你会选择一个而不是另一个?

3 个答案:

答案 0 :(得分:5)

那个的情况下它是没用的......但是假设你有一个方法:

// In Test1<T>
public List<T> GetList()
{ 
}

VS

// In Test2
public List<TestMain> GetList()
{ 
}

让我们说你有一个

public class TestSubclass: TestMain
{
}

现在,您可以:

List<TestSubclass> list1 = new Test1<TestSubclass>().GetList();

VS

List<TestMain> list2 = new Test2().GetList();

查看不同的退货类型?如果它是否有用,则取决于您如何构建程序。

我会说更常见的情况是你添加new()泛型类型约束:

public class Test1<T> where T : TestMain, new()

现在Test1你可以:

public T GetNew()
{
    return new T();
}

这是Test2无法做到的“技巧”,因为它总会返回新的TestMain()

答案 1 :(得分:0)

不同之处在于,通用变体采用T实际类型,其他只展示TestMain

所以说你要添加一个属性:

public class Test1<T> where T : TestMain
{
    public T SomeProperty { get; private set; }
    public Test1(T test)
    {
        SomeProperty = test;
    }   
}   

public class Test2
{
    public TestMain SomeProperty { get; private set; }
    public Test2(TestMain test)
    {
        SomeProperty = test;
    }
}

并说你要介绍一个派生类:

public class TestMain2 : TestMain
{
    public string Foo2 { get; set; }
}

然后在Test2中,您将无法在不进行转换的情况下访问Foo2 TestMain2.SomeProperty,而在通用类T SomeProperty中将使用所有类型Realdict公开实际的派生类型其成员。

答案 2 :(得分:0)

通用插图。

班级声明

/// <summary>
/// some base class
/// </summary>
public class BaseClass
{
    public string Name { get; set; }

    public BaseClass()
    {
        this.Name = "I'm basic class";
    }
}

/// <summary>
/// inherited class 1
/// </summary>
public class CoolClass : BaseClass
{
    public string Name { get; set; }

    public CoolClass()
    {
        this.Name = "I'm cool class :)";
    }
}

/// <summary>
/// inherited class 2
/// </summary>
public class SadClass : BaseClass
{
    public string Name { get; set; }

    public SadClass()
    {
        this.Name = "I'm sad class :(";
    }
}

/// <summary>
/// container
/// </summary>
/// <typeparam name="T"> element type </typeparam>
public class UniversalContainer<T> where T : BaseClass
{
    public List<T> Container { get; private set; }

    public UniversalContainer()
    {
        this.Container = new List<T>();
    }
}

<强>用法

UniversalContainer<string> stringContainer = new UniversalContainer<string>();      // wrong
UniversalContainer<BaseClass> baseContainer = new UniversalContainer<BaseClass>();  // right
UniversalContainer<CoolClass> coolContainer = new UniversalContainer<CoolClass>();  // right
UniversalContainer<SadClass> sadContainer = new UniversalContainer<SadClass>();     // right

baseContainer.Container.Add(new BaseClass());   // right
baseContainer.Container.Add(new SadClass());    // right
baseContainer.Container.Add(new CoolClass());   // right

coolContainer.Container.Add(new BaseClass());   // wrong
coolContainer.Container.Add(new SadClass());    // wrong
coolContainer.Container.Add(new CoolClass());   // right

sadContainer.Container.Add(new BaseClass());    // wrong
sadContainer.Container.Add(new SadClass());     // right
sadContainer.Container.Add(new CoolClass());    // wrong