标记接口:使其可互铸
本文关键字:接口 | 更新日期: 2023-09-27 18:24:50
对于流畅的API扩展方法,我有三个标记接口:
interface IOne { }
interface ITwo { }
interface IOneOrTwo : IOne, ITwo { }
以及以下扩展方法:
public static IOneOrTwo Foo (this IOne obj, string arg)
{
// do something with arg
return obj; // <- possible without cast?
}
问题:是否可以在某种程度上返回obj而不进行铸造?通常情况下,在这种情况下需要显式向下转换,但是,这些接口都不要求底层对象具有任何类型的方法/属性/anywhere。
注意:实际的实现类实现了所有的接口。
问题2:为什么实现IOne
和ITwo
不自动让实现也是IOneOrTwo
类型?
您的实现可能是向后的,让IOne
和ITwo
实现IOneOrTwo
可能会同时回答这两个问题,而不是相反。
interface IOneOrTwo { }
interface IOne: IOneOrTwo { }
interface ITwo: IOneOrTwo { }
//*** This should now work fine ***
public static IOneOrTwo Foo (this IOne obj, string arg)
{
// do something with arg
return obj;
}
澄清:
//This extension method is available to IOne, ITwo, and IOneOrTwo
public static IOneOrTwo Foo2 (this IOneOrTwo obj, string arg)
{
// do something with arg
return obj:
}
//This extension method is available only to IOne
public static IOne Foo2 (this IOne obj, string arg)
{
// do something with arg
return obj:
}
//This extension method is available only to ITwo
public static ITwo Foo2 (this ITwo obj, string arg)
{
// do something with arg
return obj:
}
在某种程度上有可能在不施法的情况下返回obj吗?
没有。类实现IOne
并不意味着它也实现IOneOrTwo
。所以你需要铸造(很可能会失败)
这些接口都不要求底层对象具有任何类型的方法/属性/任何东西。
这无关紧要。缺乏实际的方法并不会神奇地让你失望。如果一个对象实现IOne
,那么从技术上讲,它可以在不添加任何方法的情况下实现IOneOrTwo
,但它仍然需要在类定义中显式地包含该方法。
为什么实现
IOne
和ITwo
不自动让实现也是IOneOrTwo
类型
因为IOneOrTwo
可以包含不属于IOne
或ITwo
的方法。仅仅因为一个对象实现了IOne
和ITwo
,并不意味着它也实现了任何也包括这两个的接口。
您可以使用泛型得到您想要的东西:
public static T Foo<T> (this T obj, string arg) where T: IOne
{
// do something with arg
return obj;
}
那么你可以说:
IOneOrTwo obj = new IOneOrTwoImpl();
IOneOrTwo obj2 = obj.Foo("gfgfd"); // valid since obj implements IOneOrTwo
但你不能做:
IOne obj = new IOneImpl();
IOneOrTwo obj2 = obj.Foo("gfgfd"); // not valid since obj does not implement IOneOrTwo
没有石膏。
底线-接口实现必须显式地声明。仅仅因为类可以实现一个接口(意味着它包含组成该接口的所有方法/属性)并不意味着你可以把它当作实现了该接口。