接口中声明的方法的泛型返回类型,它可以接受派程度更大的返回类型
interface ICovariant<out R> { R GetSomething(); // The following statement generates a compiler error. // void SetSometing(R sampleArg); }
interface IContravariant<in A> { void SetSomething(A sampleArg); void DoSomething<T>() where T : A; // The following statement generates a compiler error. // A GetSomething(); }
<3> 协变和抗变的同时实现
interface IVariant<out R, in A> { R GetSomething(); void SetSomething(A sampleArg); R GetSetSometings(A sampleArg); }
namespace ConsoleApplication24 { // Simple hierarchy of classes. public class Person { public string FirstName { get; set; } public string LastName { get; set; } } public class Employee : Person { } // The custom comparer for the Person type // with standard implementations of Equals() // and GetHashCode() methods. class PersonComparer : IEqualityComparer<Person> { public bool Equals(Person x, Person y) { if (Object.ReferenceEquals(x, y)) return true; if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) return false; return x.FirstName == y.FirstName && x.LastName == y.LastName; } public int GetHashCode(Person person) { if (Object.ReferenceEquals(person, null)) return 0; int hashFirstName = person.FirstName == null ? 0 : person.FirstName.GetHashCode(); int hashLastName = person.LastName.GetHashCode(); return hashFirstName ^ hashLastName; } } class Program { public static void Test() { List<Employee> employees = new List<Employee> { new Employee() {FirstName = "Michael", LastName = "Alexander"}, new Employee() {FirstName = "Jeff", LastName = "Price"} }; // You can pass PersonComparer, // which implements IEqualityComparer<Person>, // although the method expects IEqualityComparer<Employee>. IEnumerable<Employee> noduplicates = employees.Distinct<Employee>(new PersonComparer()); foreach (var employee in noduplicates) Console.WriteLine(employee.FirstName + " " + employee.LastName); } public static void Main() { Test(); } } }
public delegate T SampleGenericDelegate <out T>(); public static void Test() { SampleGenericDelegate <String> dString = () => " "; // You can assign delegates to each other, // because the type T is declared covariant. SampleGenericDelegate <Object> dObject = dString; }
public static void Test() { SampleGenericDelegate<String> dString = () => " "; SampleGenericDelegate<Object> dObject = () => " "; // SampleGenericDelegate <Object> dObject = dString; //error }
原文:http://blog.csdn.net/ddupd/article/details/22698871