标记接口:使其可互铸

本文关键字:接口 | 更新日期: 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:为什么实现IOneITwo不自动让实现也是IOneOrTwo类型?

标记接口:使其可互铸

您的实现可能是向后的,让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:
}

在某种程度上有可能在不施法的情况下返回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

没有石膏。

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