C# 泛型约束

讲一下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)

原文地址:https://www.cnblogs.com/hanjun0612/p/9779834.html