当"更喜欢组合而不是继承"时生成传递代码

dev*_*xer 19 c# code-generation design-patterns visual-studio

问题

假设我试图将手机模型化为普通手机和PDA的组合.这是一种多重继承方案(手机手机,它 PDA).由于C#不支持多重继承,因此这几乎需要某种组合.另外,让我们说我还有其他理由支持作曲.

我一直想知道:是否有任何工具可以自动生成所有不可避免的传递代码?

让我用一些实际的代码充实我的例子:

接口:

public interface IPhone
{
    public void MakeCall(int phoneNumber);
    public void AnswerCall();
    public void HangUp();
}

public interface IPda
{
    public void SendEmail(string[] recipientList, string subject, string message);
    public int LookUpContactPhoneNumber(string contactName);
    public void SyncWithComputer();
}
Run Code Online (Sandbox Code Playgroud)

实现:

public class Phone : IPhone
{
    public void MakeCall(int phoneNumber) { // implementation }
    public void AnswerCall() { // implementation }
    public void HangUp() { // implementation }
}

public class Pda : IPda
{
    public void SendEmail(string[] recipientList, string subject, string message) { // implementation }
    public int LookUpContactPhoneNumber(string contactName) { // implementation }
    public void SyncWithComputer() { // implementation }
}
Run Code Online (Sandbox Code Playgroud)

CellPhone类

public class CellPhone : IPhone, IPda
{
    private IPhone _phone;
    private IPda _pda;

    public CellPhone(IPhone phone, IPda pda)
    {
        _phone = phone;
        _pda = pda;
    }

    public void MakeCall(int phoneNumber)
    {
        _phone.MakeCall(phoneNumber);
    }

    public void AnswerCall()
    {
        _phone.AnswerCall();
    }

    public void HangUp()
    {
        _phone.HangUp();
    }

    public void SendEmail(string[] recipientList, string subject, string message)
    {
        _pda.SendEmail(recipientList, subject, message);
    }

    public int LookUpContactPhoneNumber(string contactName)
    {
        return _pda.LookUpContactPhoneNumber(contactName);
    }

    public void SyncWithComputer()
    {
        _pda.SyncWithComputer();
    }
}
Run Code Online (Sandbox Code Playgroud)

编写CellPhone类很繁琐且容易出错:

所有这一类真正做的就是充当PhonePda类的管道.实际上没有理由要求人们努力输入所有这些传递语句(如_phone.MakeCall(phoneNumber);).它只暴露了几个成员字段的公共接口.

问题

  1. 有没有一个工具(最好是免费的:)),这将使我免于容易出错的写作传递方法的单调乏味?我知道我可以使用VS自动生成存根,但这只能让我获得一半.

  2. 你能评价这种功能的可行性和可取性吗?是否值得向微软提出添加此类代码生成的建议?如果我这样做,你会投票吗?如果没有,你有什么反对意见?

编辑

每个人似乎都在说同样的事情:为什么不让我做_phone,并_pda纳入公共属性?我对此的反对意见是它违反了"最少知识原则".我CellPhone班上的客户应该只做手机所做的事情,不应该去弄清楚哪些功能是Phone功能,哪些是Pda功能.这会产生额外的依赖关系,并使CellPhone接口的功能不那么明显.

另外,不要只关注这个例子.如果我正在编写适配器怎么办?它可能包含几个只是传递的接口成员,但它也可能包含一些具有唯一实现的唯一成员.我相信在很多情况下,传递代码是一件好事,我只是不喜欢写它.

Mar*_*son 17

是的,您可以使用精彩的VS插件ReSharper生成方法

从代码生成菜单中选择" 生成委派方法 "选项(使用默认快捷方案的Alt-Insert).

如果你有一个实现接口的类,包含一个实现相同接口的字段,R#将为你提供一个生成传递代码的选项.它也可以与任意数量的接口一起使用.