泛型类型参数及约束

  • 泛型类型参数简介

    在定义泛型类型和泛型方法时,常用到泛型类型参数,泛型类型参数是在实例化泛型时指定类型的占位符。泛型类型参数放在“<>”内。

    泛型类型参数命名建议:

    (1)当泛型类型参数为单个字母时,建议用T表示。

    (1)当泛型类型参数用单词定义时,建议在单词前加T。

private void PromptName<T>(T t) {}
private void PromptName<Tuser>(Tuser user){}
  • 泛型类型参数约束

      在定义泛型类时,可以对在实例化泛型类时用于类型参数的类型种类施加限制。如果实例化泛型类时使用某个约束所不允许的类型来实例化类,则会产生编译时错误。

      泛型约束分类:  

约束

说明

T:结构

类型参数必须是值类型。 可以指定除 Nullable 以外的任何值类型。

T:类

类型参数必须是引用类型;这一点也适用于任何类、接口、委托或数组类型。

T:new()

类型参数必须具有无参数的公共构造函数。 当与其他约束一起使用时,new() 约束必须最后指定。

T:<基类名>

类型参数必须是指定的基类或派生自指定的基类。

T:<接口名称>

类型参数必须是指定的接口或实现指定的接口。 可以指定多个接口约束。 约束接口也可以是泛型的。

T:U

为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数。

 (1)类型参数约束为结构(struct)。

    public class ShowObjectType<T> where T : struct
    {
        public void ShowValue<T>(T t)
        {
            Console.WriteLine(t.GetType());
        }
    }

    class GenericConstraint
    {
        static void Main()
        {
          
            ShowObjectType<int> showInt = new ShowObjectType<int>();
            showInt.ShowValue<int>(5);
            showInt.ShowValue(5);//从参数可以推导出类型参数类型,则可以省略类型参数类型
            
            //因为约束为值类型,下面代码不能通过编译
            ShowObjectType<string> showString = new ShowObjectType<string>();
            showString.ShowValue("5");

            Console.Read();
        }

    }

   (2)类型参数约束为类(class)。

    在应用 where T : class 约束时,避免对类型参数使用 ==!= 运算符,因为这些运算符仅测试类型为引用类型,而不测试值相等性。

    class GenericConstraint
    {
        static void Main()
        {
              List<string > list = new List<string>();
            AddClass<string>(list, "hello generic");

            Console.Read();
        }

        private static void AddClass<T>(List<T> list, T t) where T : class
        {
            list.Add(t);
        }
    }

  (4)类型参数约束为具体类。

         约束为具体类时,可利用类型参数调用具体类的属性和方法。

    class GenericConstraint
    {
        static void Main()
        {
            Person person = new Person { ID = 1, Name = "David" };
            PromptName<Person>(person);

            Console.Read();
        }

        //此约束T为Person对象或者继承Person对象
        private static void PromptName<T>(T t) where T : Person 
        {
            //此处可使用Person的Name属性
            if (t.Name == "David")
            {
                Console.WriteLine("Person name is David");
            }

            string name = t.GetName();
            Console.WriteLine("Person name is {0}", name);
        }
    }
    public class Person
    {
        private int id;
        public int ID
        {
            get { return id; }
            set { id = value; }
        }

        private string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        public string GetName()
        {
            return Name;
        }
    }

    (5)约束多个参数。

class Base { }
class Test<T, U>
    where U : struct
    where T : Base, new() { }

    (6)未绑定类型参数。

      没有约束的类型参数,称为未绑定的类型参数。

class  List<T>{}

 

posted @ 2012-07-11 21:10  蒹葭白露  阅读(13032)  评论(1编辑  收藏  举报