zoukankan      html  css  js  c++  java
  • 泛型类型参数及约束

    泛型类型参数简介

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

        泛型类型参数命名建议:

        (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>{}
  • 相关阅读:
    解决Struts中文乱码问题总结
    也谈创业企业CEO该拿多少工资
    Codeforces Round #242 (Div. 2) A. Squats
    设计模式之模板方法模式
    hdu2768Cat vs. Dog (反建法,最大独立集)
    Python
    kvm
    linux bin文件制作
    python
    pytho
  • 原文地址:https://www.cnblogs.com/ChineseMoonGod/p/5175810.html
Copyright © 2011-2022 走看看