【问题标题】:Interface Delegation in C#C# 中的接口委托
【发布时间】:2012-07-05 18:34:04
【问题描述】:

在 Delphi 中,我们可以将接口的实现委托给另一个类,我想知道这在 C# 中是否可行?

例如,我有接口 IMyInterface,我说 TMyClass 实现了 IMyInterface。但实际上并没有。在内部,我可以使用 implements 关键字将接口实现委托给另一个类,而无需在 TMyClass 中声明每个方法。

【问题讨论】:

    标签: c# delphi interface


    【解决方案1】:

    有一个简单的答案:不,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...
    

    其中DoThisDoThatISomeInterface 的方法,必须由Blah 实现。在 C# 中,您必须将这些方法中的每一个显式委托给包含的接口。在 Delphi 中,当您在 classinterface 类型的属性后使用 implements 关键字时,这是自动完成的(即,在幕后生成和调用方法,对用户不可见)。

    我假设一些回答者对使用术语 implementsdelegation 感到困惑,它们在 C# 中具有不同的含义。

    【讨论】:

    • +1 感谢您,在阅读了您提供的 Delphi 文档后,我现在看到您的答案确实最接近标记。我已经删除了我的。
    • 事实上你提到的解决方案叫做封装。
    • FWIW,Delphi 不生成任何包装方法。它只是直接操作接口的方法调用表,所以直接调用实现接口或类的方法。
    • 我想知道为什么“在 c# 中通过委托实现接口”没有得到任何有意义的结果。您能否详细说明这些术语在 C# 世界中的使用方式有何不同,尤其是哪些替代术语可能会产生更有意义的结果?当然,至少有一些关于将其作为新功能添加到 C# 的讨论?
    【解决方案2】:

    在 C# 中,您不能委托类的接口实现,除非通过继承(参见 Nikola Anusev 的答案)。

    但是,您可以使用部分类定义将接口实现与类的其余部分分开。

    在一个 (MyClass.Specific.cs) 文件中,您拥有:

    public partial class MyClass
    {
        void MySpecificMethod() {...}
    }
    

    而在另一个文件 (MyClass.IMyInterface.cs) 中,您只有特定于类的方法:

    public partial class MyClass : IMyInterface
    {
        void IMyInterface.MySpecificMethod() {...}
    }
    

    您仍然拥有 MyClass 中的所有方法,但在不同的文件中。

    【讨论】:

    • Delphi 中的接口委托是可以在运行时切换的(通过简单地将属性设置为不同的接口或类),因此这个编译时解决方案几乎不是等效的。
    【解决方案3】:

    您可以使用部分类,这将使您可以将实现放到不同的文件中,类的两个部分应该在同一个程序集中。

    Class1.cs

    public partial class Class1: IInterface {}
    

    Class1Impl.cs

    public partial class Class1 { /*implementation */ }
    

    我无法想象另一种方式来做你想做的事。 只需使用封装 =) 这不是您真正想要的,您必须编写一些存根代理方法。

    【讨论】:

    • 这不是 Delphi 的“implements”关键字所做的,这就是 OP 的意思。
    【解决方案4】:

    你可以使用partial classes:

    // SomeThing.cs
    public partial class SomeThing
    {
       // your interface independant part
    }
    
    // SomeThing.ISomeThing.cs
    public partial class SomeThing: ISomeThing
    {
       // ISomeThing implementation
    }
    

    这两个文件需要在同一个程序集中。它们被编译器组合成一个类。

    【讨论】:

    • 这也不是 Delphi 中的接口委托所做的。
    【解决方案5】:

    我认为没有任何实用的方法。您可以将实现类编写为抽象类,这反过来又变得相当笨拙,因为您不能再实例化第一个类。唯一的办法就是写一些丑陋的空虚方法,像这样:

    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 接口,请将其废弃。将接口写成一个抽象类来开始和实现一些方法,要容易得多。

    【讨论】:

    • 这不是自动委托实现接口的意思。在 Delphi 中,您可以让一个属性实现一个接口来代替具有该属性的类。对类上的接口的调用透明地路由到属性的相应方法。当然,它可以明确地完成。请注意,这与使用抽象类不同。这就像显式调用包含的对象或接口的方法。
    • 我刚刚告诉过你,C# 没有。我为您提供了替代方案,但归根结底,答案很简单:不,没有 C# 等价物。
    • 你提供的不是替代品,AFAICT。这是不同的东西。
    猜你喜欢
    • 2012-01-31
    • 2012-06-25
    • 1970-01-01
    • 2012-02-11
    • 2014-08-18
    • 2021-02-20
    • 2020-08-22
    • 1970-01-01
    • 2023-04-08
    相关资源
    最近更新 更多