我有三个标记接口,用于流畅的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?通常,您需要在这种情况下明确地向下转换,但是,这些接口都不要求底层对象具有任何类型的方法/属性/无论如何。
注意:实际的实现类实现了所有接口。
问题2:为什么实施IOne
和ITwo
不会自动让实施也属于IOneOrTwo
类型?
答案 0 :(得分:6)
您的实施似乎可能是落后的,可以回答您的两个问题,让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:
}
答案 1 :(得分:1)
以某种方式可以在没有强制转换的情况下返回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
没有演员。
底线 - 接口实现必须显式声明。仅仅因为一个类可以实现一个接口(意味着它包含构成该接口的所有方法/属性)并不意味着你可以将它视为 实现该接口。