讲一下C# 泛型
不知道的朋友,看一下下面代码就明白了
public interface IDigitDevice<T>
{
List<T> Search(string s);
}
其中,T 就是我们说的泛型。
它有6种约束
约束 | 说明 |
---|---|
T:结构 | 类型参数必须是值类型。 可以指定除 Nullable 以外的任何值类型。 有关更多信息,请参见使用可以为 null 的类型。 |
T:类 | 类型参数必须是引用类型;这一点也适用于任何类、接口、委托或数组类型。 |
T:new() | 类型参数必须具有无参数的公共构造函数。 当与其他约束一起使用时,new() 约束必须最后指定。 |
T:<基类名> | 类型参数必须是指定的基类或派生自指定的基类。 |
T:<接口名称> | 类型参数必须是指定的接口或实现指定的接口。 可以指定多个接口约束。 约束接口也可以是泛型的。 |
T:U | 为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数。 |
T:类
T:结构
class MyClass<T, U>
where T : class///约束T参数必须为“引用 类型{ }”
where U : struct///约束U参数必须为“值 类型”
{ }
T:new()
class EmployeeList<T> where T : new()
{
}
T:<基类名>
public class MyClass<T> where T : BaseClass
{
}
T:<接口名称>
public class MyClass<T> where T : IBaseClass
{
}
U:T (msdn上标题是T:U,但实际上T是U的约束,所以我改过来了U : T)
class List<T>
{
void Add<U>(List<U> items) where U : T {/*...*/}
}
对于这个,我们看下例子就知道了:
static void Main(string[] args)
{
List<B> l = new List<B>();
List<A> t = new List<A>();
t.Add<B>(l);
Console.ReadLine();
}
public class List<T>
{
public void Add<U>(List<U> items) where U : T {/*...*/}
}
public class A { }
//关键就是 B继承自A(U : T)
public class B:A { }
Test<T , U> 多个泛型约束
class Base { }
class Test<T, U>
where U : struct
where T : Base, new() { }
实战:
正好论坛上,有朋友问了个问题,然后我就写了个泛型简单工厂的例子。
一。
static void Main(string[] args)
{
//传入 PCInfo
var q = MyFactory<PCInfo>.CreateOperation();
foreach (var item in q.Search("1"))
{
Console.WriteLine(item.id + " " + item.num);
}
Console.WriteLine("-------------------");
//传入TelephoneInfo
var v = MyFactory<TelephoneInfo>.CreateOperation();
foreach (var item in q.Search("1"))
{
Console.WriteLine(item.id + " " + item.num);
}
Console.ReadLine();
}
//接口 IDigitDevice
public interface IDigitDevice<T>
{
List<T> Search(string s);
}
//PCSearch 派生自 IDigitDevice
public class PCSearch : IDigitDevice<PCInfo>
{
public List<PCInfo> Search(string s)
{
var q = new List<PCInfo>(){
new PCInfo(){id=1,num="123"},
new PCInfo(){id=2,num="222"},
};
return q;
}
}
//TelephoneSearch 派生自 IDigitDevice
public class TelephoneSearch : IDigitDevice<TelephoneInfo>
{
public List<TelephoneInfo> Search(string s)
{
var q = new List<TelephoneInfo>(){
new TelephoneInfo(){id=101,num="asdf"},
new TelephoneInfo(){id=102,num="cccc"},
};
return q;
}
}
//简单工厂
public class MyFactory<T>
{
public static IDigitDevice<T> CreateOperation()
{
IDigitDevice<T> o = null;
if (typeof(T).Name == "PCInfo")
o = (IDigitDevice<T>)new PCSearch();
else if (typeof(T).Name == "TelephoneInfo")
o = (IDigitDevice<T>)new TelephoneSearch();
return o;
}
}
//实体层
public class PCInfo
{
public int id { get; set; }
public string num { get; set; }
}
public class TelephoneInfo
{
public int id { get; set; }
public string num { get; set; }
}
上面的还是比较好理解的。
下面我们在看看,稍微难一点的。
二。
static void Main(string[] args)
{
var q = MyFactory<PCSearch,PCInfo>.CreateOperation();
foreach (var item in q.Search("1"))
{
Console.WriteLine(item.id+" "+item.num);
}
Console.WriteLine("-------------------");
var v = MyFactory<TelephoneSearch,TelephoneInfo>.CreateOperation();
foreach (var item in v.Search("1"))
{
Console.WriteLine(item.id + " " + item.num);
}
Console.ReadLine();
}
public interface IDigitDevice<T>
{
List<T> Search(string s);
}
public class PCSearch : IDigitDevice<PCInfo>
{
public List<PCInfo> Search(string s)
{
var q = new List<PCInfo>(){
new PCInfo(){id=1,num="123"},
new PCInfo(){id=2,num="222"},
};
return q;
}
}
public class TelephoneSearch : IDigitDevice<TelephoneInfo>
{
public List<TelephoneInfo> Search(string s)
{
var q = new List<TelephoneInfo>(){
new TelephoneInfo(){id=101,num="asdf"},
new TelephoneInfo(){id=102,num="cccc"},
};
return q;
}
}
public class MyFactory<T, S> where T : IDigitDevice<S>,new()
{
public static IDigitDevice<S> CreateOperation()
{
IDigitDevice<S> o = (IDigitDevice<S>)new T();
return o;
}
}
public class PCInfo {
public int id { get; set; }
public string num { get; set; }
}
public class TelephoneInfo {
public int id { get; set; }
public string num { get; set; }
}
第一个例子,是给工厂传入了实体对象。
第二个例子,是给工厂传入实体对象的同时,告诉他调用哪个实现类(PCSearch 还是 TelephoneSearch)