泛型接口:使成员的参数和返回值都可以是类型参数
自定义泛型接口
interface IDoSomeAble<T>
{
string GetFullName(T type);
}
用泛型类实现泛型接口
class TestClass<T> : IDoSomeAble<T>
{
public string GetFullName(T type)
{
return type.GetType().FullName;
}
}
在Main方法中测试泛型接口
class Program
{
static void Main(string[] args)
{
IDoSomeAble<int> intDemo=new TestClass<int>();
var rtnVlaue= intDemo.GetFullName(1);
Console.WriteLine(rtnVlaue);
IDoSomeAble<string> stringDemo=new TestClass<string>();
var rtnStr= stringDemo.GetFullName("");
Console.WriteLine(rtnStr);
Console.ReadLine();
}
}
/*
输出:
System.Int32
System.String
*/
与其它泛型类型:类型参数的类型不同,构造出来的泛型接口是不同的接口
static void Main(string[] args)
{
var ss = typeof(IDoSomeAble<int>);
var tt = typeof(IDoSomeAble<string>);
Console.WriteLine(ss==tt);
var intType = typeof(int);
var intType2 = typeof(int);
Console.WriteLine(intType==intType2);
Console.ReadLine();
}
/*
输出:
False
True
*/
所以非泛型类能够实现多个不同类型参数的泛型接口
class Program
{
static void Main(string[] args)
{
TestClass testClass = new TestClass();
var s1 = testClass.GetFullName(1);
Console.WriteLine(s1);
var s2 = testClass.GetFullName("1");
Console.WriteLine(s2);
Console.ReadLine();
}
}
interface IDoSomeAble<T>
{
string GetFullName(T type);
}
class TestClass : IDoSomeAble<int>, IDoSomeAble<string>
{
public string GetFullName(int type)
{
Console.WriteLine("实现了类型实参为int的泛型接口");
return type.GetType().FullName;
}
public string GetFullName(string type)
{
Console.WriteLine("实现了类型实参为string的泛型接口");
return type.GetType().FullName;
}
}
/*
输出:
实现了类型实参为int的泛型接口
System.Int32
实现了类型实参为string的泛型接口
System.String
*/
泛型类也能够实现多个泛型接口 但是要注意下面这种情况
interface IDoSomeAble<T>
{
string GetFullName(T type);
}
class TestClass<S> : IDoSomeAble<int>, IDoSomeAble<S>
{
public string GetFullName(int type)
{
Console.WriteLine("实现了类型参数为int类型的泛型接口");
return type.GetType().FullName;
}
public string GetFullName(S type)
{
Console.WriteLine("实现了IDoSomeAble<S>接口");
return type.GetType().FullName;
}
}
/*
编译报错:
Program.cs(28, 11): [CS0695] ‘“TestClass<S>”不能同时实现“IDoSomeAble<int>”和“IDoSomeAble<S>”,原因是它们可以统一以进行某些类型参数替换
*/
因为上面的代码中,第二个类型参数为S的泛型接口,一旦使用int类型实参来替换类型参数,那么就会在运行时出现一个类实现了两个一摸一样的接口的情景;所以为避免这种可能出现,编辑器在编译器就提示错误。
泛型接口相较非泛型接口更灵活
我在C#:接口这篇博客中通过继承IComparable接口,使类型可排序;但是.NET提供了更为高效的解决方式
通过实现泛型接口IComparable< Student >,使类型可排序
class Program
{
static void Main(string[] args)
{
Student tangsan = new Student() {StudentName = "唐三", StudentAge = 17, ClassGroup = "史莱克学院"};
Student xiaowu = new Student() {StudentName = "小舞", StudentAge = 19, ClassGroup = "史莱克学院"};
Student pangzi = new Student() {StudentName = "胖子", StudentAge = 18, ClassGroup = "史莱克学院"};
Student daimubai = new Student() {StudentName = "戴沐白", StudentAge = 20, ClassGroup = "史莱克学院"};
Student[] students = new Student[] {tangsan, xiaowu, pangzi, daimubai};
Array.Sort(students);
foreach (var item in students)
{
Console.WriteLine(item);
}
Console.ReadLine();
}
}
class Student : IComparable<Student>
{
public string StudentName { get; set; }
public int StudentAge { get; set; }
public string ClassGroup { get; set; }
public override string ToString()
{
return $"{this.ClassGroup}:{this.StudentName},{this.StudentAge}";
}
public int CompareTo(Student other)
{
if (ReferenceEquals(this, other)) return 0;
if (ReferenceEquals(null, other)) return 1;
var studentAgeComparison = StudentAge.CompareTo(other.StudentAge);
if (studentAgeComparison != 0) return studentAgeComparison;
var studentNameComparison = string.Compare(StudentName, other.StudentName, StringComparison.Ordinal);
if (studentNameComparison != 0) return studentNameComparison;
return string.Compare(ClassGroup, other.ClassGroup, StringComparison.Ordinal);
}
}
/*
输出:
史莱克学院:唐三,17
史莱克学院:胖子,18
史莱克学院:小舞,19
史莱克学院:戴沐白,20
*/
上述示例仅为演示泛型接口也可实现类型排序的能力,写法上并不完善;可参见.NET API 详细了解IComparable和IComparable
以上便是对泛型接口的知识总结,记录下来一边以后查阅。