【发布时间】:2012-07-05 18:34:04
【问题描述】:
在 Delphi 中,我们可以将接口的实现委托给另一个类,我想知道这在 C# 中是否可行?
例如,我有接口 IMyInterface,我说 TMyClass 实现了 IMyInterface。但实际上并没有。在内部,我可以使用 implements 关键字将接口实现委托给另一个类,而无需在 TMyClass 中声明每个方法。
【问题讨论】:
在 Delphi 中,我们可以将接口的实现委托给另一个类,我想知道这在 C# 中是否可行?
例如,我有接口 IMyInterface,我说 TMyClass 实现了 IMyInterface。但实际上并没有。在内部,我可以使用 implements 关键字将接口实现委托给另一个类,而无需在 TMyClass 中声明每个方法。
【问题讨论】:
有一个简单的答案:不,C# 不允许它以与 Delphi 相同的方式。
对于那些了解 C# 但不了解 Delphi 的人,这意味着:http://docwiki.embarcadero.com/RADStudio/en/Implementing_Interfaces,请参阅“通过委托实现接口(仅限 Win32)”部分。
我猜你必须手动将方法调用传递给接口。我的 C# 有点生疏(不过我仍然可以很好地阅读它):
public class Blah : ISomeInterface
{
public ISomeInterface implementer { getter and setter here }
public int ISomeInterface.DoThis()
{
if (implementer) return implementer.DoThis();
}
public void ISomeInterface.DoThat(int param)
{
if (implementer) implementer.DoThat(param);
}
etc...
其中DoThis 和DoThat 是ISomeInterface 的方法,必须由Blah 实现。在 C# 中,您必须将这些方法中的每一个显式委托给包含的接口。在 Delphi 中,当您在 class 或 interface 类型的属性后使用 implements 关键字时,这是自动完成的(即,在幕后生成和调用方法,对用户不可见)。
我假设一些回答者对使用术语 implements 和 delegation 感到困惑,它们在 C# 中具有不同的含义。
【讨论】:
在 C# 中,您不能委托类的接口实现,除非通过继承(参见 Nikola Anusev 的答案)。
但是,您可以使用部分类定义将接口实现与类的其余部分分开。
在一个 (MyClass.Specific.cs) 文件中,您拥有:
public partial class MyClass
{
void MySpecificMethod() {...}
}
而在另一个文件 (MyClass.IMyInterface.cs) 中,您只有特定于类的方法:
public partial class MyClass : IMyInterface
{
void IMyInterface.MySpecificMethod() {...}
}
您仍然拥有 MyClass 中的所有方法,但在不同的文件中。
【讨论】:
您可以使用部分类,这将使您可以将实现放到不同的文件中,类的两个部分应该在同一个程序集中。
Class1.cs
public partial class Class1: IInterface {}
Class1Impl.cs
public partial class Class1 { /*implementation */ }
我无法想象另一种方式来做你想做的事。 只需使用封装 =) 这不是您真正想要的,您必须编写一些存根代理方法。
【讨论】:
你可以使用partial classes:
// SomeThing.cs
public partial class SomeThing
{
// your interface independant part
}
// SomeThing.ISomeThing.cs
public partial class SomeThing: ISomeThing
{
// ISomeThing implementation
}
这两个文件需要在同一个程序集中。它们被编译器组合成一个类。
【讨论】:
我认为没有任何实用的方法。您可以将实现类编写为抽象类,这反过来又变得相当笨拙,因为您不能再实例化第一个类。唯一的办法就是写一些丑陋的空虚方法,像这样:
public interface ISomething
{
void DoOne();
void DoTwo();
}
public class Something : ISomething
{
public virtual void DoOne() { }
public virtual void DoTwo() { }
}
但这是一个糟糕的类设计 IMO,因为您确实应该首先制作实现类 abstract,因此人们无法实例化实现虚假接口的类的实例。
因此,正确的方法是在您的“抽象”类中部分实现接口,并通过将其他类标记为抽象来将它们委托给继承类(直到要实现的派生类)。
即
public interface ISomething
{
void DoOne();
void DoTwo();
}
public abstract class Something : ISomething
{
public abstract void DoOne();
public abstract void DoTwo();
}
这样,没有人可以直接实例化你不稳定的“Something”类,但派生类仍然需要来实现尚未实现的接口的抽象方法。这更加健壮和安全。
请注意,如果您正在实现的是您的 OWN 接口,请将其废弃。将接口写成一个抽象类来开始和实现一些方法,要容易得多。
【讨论】: