C#中泛型(下)

上一节介绍了泛型类和泛型方法,下面着重介绍泛型接口。

接口:表示纯粹抽象的行为,不能有构造函数和字段,成员是隐式公有的(不能使用修饰符),接口名一般以大写字母 I 开头。

注意:虽然接口不能实例化,但可以声明接口类型的变量并使用实现接口的非抽象类或结构体实例化(抽象类可以使用非抽象子类实例化)。

泛型接口:在接口名后面加上 <T> 声明,也可以在后面添加约束。

1、方法的协变与抗变

协变:方法的参数是基类时,可以使用子类的对象来代替。

抗变:方法的返回值是基类时,不能赋值给子类的引用。

下面给出示例:

public class  BaseC
{

}
public class SubC:BaseC
{

}
public class Test
{
	public static BaseC GetType(BaseC obj)
	{
		return null;
	}
}
调用方法:

BaseC obj = new SubC();
// 协变:使用子类的实例化对象代替参数
Test.GetType(obj);
// 抗变:返回值是基类类型时不能赋值给子类引用
BaseC obj1 = Test.GetType(new SubC());
2、泛型接口的协变与抗变

协变:使用 out 关键字修饰,形式 :< out  T >,类型 T 只能作为接口成员的返回类型,用子类指定的泛型接口对象可以赋值给用基类指定的泛型接口引用。

抗变:使用 in   关键字修饰,形式:     < in  T >,类型 T 只能用作方法的输入,用基类指定的泛型接口对象可以赋值给用子类指定的泛型接口引用。

下面给出示例:

public class  BaseC
{

}
public class SubC:BaseC
{

}
// out 修饰:类型 T 只能用作方法的返回
public interface ITestOut<out T>
{
	T GetCurrType();
}
// 用来测试协变
public class TestOut:ITestOut<SubC>
{
	public SubC GetCurrType()
	{
		return new SubC();
	}
	// 返回该类的一个实例
	public static TestOut GetITestOut()
	{
		return  new TestOut();
	}
}
// in 修饰:类型 T 只能用作方法的输入
public interface ITestIn<in T>
{
	void GetCurrType(T obj);
}
// 用来测试抗变
public class TestIn:ITestIn<BaseC>
{
	public void GetCurrType(BaseC obj)
	{

	}
}
调用示例:

// 1、泛型接口协变:子类指定的对象赋值给基类指定的引用
ITestOut<SubC> subC = TestOut.GetITestOut(); // 该方法得到一个 TestOut 类的实例
ITestOut<BaseC> baseC = subC;

// 2、泛型接口抗变:基类指定的对象赋值给子类指定的引用
ITestIn<BaseC> baseC1 = new  TestIn(); // 接口可以用实现他的类的实例去实例化
ITestIn<SubC> subC1 = baseC1;

抽象类和接口的区别点击打开链接


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值