标记接口:使它们可互换

时间:2013-07-24 18:07:21

标签: c# marker-interfaces

我有三个标记接口,用于流畅的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:为什么实施IOneITwo不会自动让实施也属于IOneOrTwo类型?

2 个答案:

答案 0 :(得分:6)

您的实施似乎可能是落后的,可以回答您的两个问题,让IOneITwo实施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而不添加任何方法,但它仍然需要在类定义中明确地包含它。

  

为什么实施IOneITwo不会自动让实现也属于IOneOrTwo类型

因为IOneOrTwo 可以包含不属于IOneITwo的方法。仅仅因为一个对象实现IOneITwo并不意味着它也实现了任何包含这两个接口的接口。

可以使用泛型获得你想要的东西:

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

没有演员。

底线 - 接口实现必须显式声明。仅仅因为一个类可以实现一个接口(意味着它包含构成该接口的所有方法/属性)并不意味着你可以将它视为 实现该接口。