给出一个课程:
public class TestMain
{
}
两个类接受这个类的实例,一个通过泛型:
public class Test1<T> where T : TestMain
{
public Test1(T test)
{
}
}
一个没有:
public class Test2
{
public Test2(TestMain test)
{
}
}
为什么你会选择一个而不是另一个?
答案 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