我在接口Use<T>
中定义了一个通用方法IInterface
。我尝试创建该接口的实现,其中Use<T>
方法的具体实现取决于实际类型T
,并且我希望始终调用最专业的方法。但它不起作用:
interface IInterface { void Use<T>(T other) where T : IInterface; }
interface IChildInterface : IInterface { }
class ImplementsIInterface : IInterface
{
public void Use<T>(T other) where T : IInterface
{
Debug.WriteLine("ImplementsInterface.Use(IInterface)");
}
}
class ImplementsChildInterface : IChildInterface
{
public void Use<T>(IChildInterface other) where T : IInterface
{ // idea: if other is IChildInterface, use this method
Debug.WriteLine("ImplementsChildInterface.Use(IChildInterface)");
}
public void Use<T>(T other) where T : IInterface
{ // idea: if above method is not applicable, use this method
Debug.WriteLine("ImplementsChildInterface.Use(IInterface)");
}
}
这是我的主要方法:
public static void Main()
{
IChildInterface childinterf = new ImplementsChildInterface();
childinterf.Use(new ImplementsChildInterface()); // outputs "ImplementsChildInterface.Use(IInterface)"
// but should output "ImplementsChildInterface.Use(IChildInterface)"
childinterf.Use(new ImplementsIInterface()); // outputs "ImplementsChildInterface.Use(IInterface)"
}
从不调用带有IChildInterface
参数的方法,尽管它应该。
有没有办法让这项工作?或者我的方法根本错误?
请注意,IInterface
只需要一个方法定义。我可以随时扩大接口层次结构(从而增加我可以在实现类中提供的实现数量),但这不应该导致需要在IInterface
中添加更多方法定义。否则,将错过使用界面的整个要点(即灵活)。
到目前为止我得到的答案都涉及到施放的必要性。这也是我不想做的事情,因为它使整个设置无用。让我解释一下我试图实现的更广泛的情况:
让我们假设我们创建了一个IInterface
的实例(如此:IInterface foo = new ImplementsChildInterface();
)。它将以某种方式运行,但它始终以相同的方式运行 - 无论我们将其视为IInterface
,IChildInterface
还是ImplementsChildInterface
。因为,如果我们在其上调用某个方法,编译器(或运行时?我不知道)将检查它真正的类型并运行该类型中定义的方法。
现在假设我们有两个i1
和i2
IInterface
的实例。它们又是IInterface
的具体实现,所以它们具有一种具体的行为,无论我们看起来是哪种眼镜。
因此,当我运行i1.Use(i2)
时,编译器(或运行时?)应该能够找出i1
和i2
真正的内容,并运行相应的方法。像这样:
i1
有哪种类型? ImplementsChildInterface
,好的,然后我会看看那里的方法。i2
有哪种类型? ImplementsIInterface
,好的,然后让我们看看是否存在方法Use(ImplementsIInterface ...)
。没有,但也许有一个后备? ImplementsIInterface
是IInterface
,所以让我们看看是否存在方法Use(IInterface ...)
。是的,它存在,所以我们称之为!答案 0 :(得分:2)
IInterface
和IChildInterface
都没有定义成员Use<T>(IChildInterface other)
,只有Use<T>(T other)
。
另一方的您的课程ImplementsChildInterface
有Use<T>(IChildInterface other)
方法。当您将childInterf
声明为类型IChildInterface
的引用时,您无法访问该成员,但不能访问界面中定义的成员。因此,您应该转换为实际的类,以便访问接受IChildInterface
实例的方法。但即使这样,也使用了通用实现。因此,您还应将参数转换为IchildInterface
:
ImplementsChildInterfacechildinterf = new ImplementsChildInterface();
childinterf.Use(((IChildInterface)new ImplementsChildInterface());
childinterf.Use(new ImplementsIInterface());
此外,由于您没有在更专业的方法中使用泛型类型参数,因此您也可以省略它:
class ImplementsChildInterface : IChildInterface
{
public void Use(IChildInterface other)
{ // idea: if other is IChildInterface, use this method
Debug.WriteLine("ImplementsChildInterface.Use(IChildInterface)");
}
public void Use<T>(T other) where T : IInterface
{ // idea: if above method is not applicable, use this method
Debug.WriteLine("ImplementsChildInterface.Use(IInterface)");
}
}
另外,您也可以在IChildInterface
:
void Use<T>(IChildInterface other) where T : IChildInterface;
现在你可以使用
IChildInterface childinterf = new ImplementsChildInterface();
childinterf.Use<IChildInterface>(new ImplementsChildInterface()); // outputs "ImplementsChildInterface.Use(IInterface)"
将打印所需的输出。