c# 泛型之约束

1.1类类型约束

  有时候可能要求能将类型实参转换为特定的类类型,这是用类类型约束做到的。

 public class TestDictionary<TKey, TValue> : Dictionary<TKey, TValue> where TValue : EntityBase
 { }

如上述代码,TestDictionary<TKey, TValue> 要求类型参数TValue提供的所有类型参数都必须隐式的转换为EntityBase类。

与接口约束不同,不允许多个类类型约束。c#不允许将类型参数约束为string或者System.Nullable<T>,否则就只有单一类型实参可供选择,类型参数就没必要存在了,直接用这个类型即可  

 1.2接口约束

 IComparable是一个接口,可以排序或排序的类型实现

 public    class Program
 {
     public class Container<T, U>
     {
         /// <summary>
         /// 嵌套类
         /// </summary>
         /// <typeparam name="U"></typeparam>
         public class Nested<U>
         {
             public void Method(T t, U u)
             {
             }
         }

     }
       public  static void Main(string[] args)
        {
//这时候会报错 不能将类型“System.Text.StringBuilder”用作泛型类型或方法“ConsoleApplication2.BinaryTree<T>”中的类型形参“T”。没有从“System.Text.StringBuilder”到“System.IComparable<System.Text.StringBuilder>”的隐式引用转换。
 
            BinaryTree<StringBuilder> b = new BinaryTree<StringBuilder>();
//下面的就可以
            BinaryTree<int> b = new BinaryTree<int>();
BinaryTree<string> b = new BinaryTree<string>();
 } } 
//这是为了这个类中的方法实现而加的对参数的约束。
public class BinaryTree<T> where T : IComparable<T> {

}

1.3struct/class约束

IFormattable接口提供了ToString()方法的定义,使用该方法可以将对象的值按照指定的格式转化成字符串的功能

下面代码是示例:

 public class Program
    {
        static void Main(string[] args)
        {
            Person p1 = new Person { FirstName = "XY", LastName = "CN" };
            PersonFormatter pf = new PersonFormatter();
            string s1 = p1.ToString("CN", pf);
            Console.WriteLine(s1);
            string s2 = p1.ToString("EN", pf);
            Console.WriteLine(s2);
            string s3 = p1.ToString("EN", null);
            Console.WriteLine(s3);
            Console.ReadKey();
        }
    }

    class PersonFormatter : IFormatProvider,ICustomFormatter
    {
        public string Format(string format, object arg, IFormatProvider formatProvider)
        {
            Person person = arg as Person;
            switch(format)
            {
                case "CH":return string.Format("{0} {1}",person.LastName,person.FirstName); //$"{person.LastName} {person.FirstName}";
                case "EN": return string.Format("{0} {1}", person.FirstName, person.LastName);//$"{person.FirstName} {person.LastName}";
                default: return string.Format("{0} {1}", person.LastName, person.FirstName);//$"{person.LastName} {person.FirstName}";
            }
        }

        public object GetFormat(Type formatType)
        {
            if (formatType == typeof(ICustomFormatter)) return this;
            return null;
        }
    }

    class Person:IFormattable
    {
        public string FirstName { set; get; }
        public string LastName { set; get; }

        public string ToString(string format, IFormatProvider formatProvider)
        {
            ICustomFormatter customFormatter = formatProvider as ICustomFormatter;
            if (customFormatter == null) return this.ToString();
            return customFormatter.Format(format, this, null);
        }
    }

   
原文地址:https://www.cnblogs.com/anjingdian/p/12198597.html