首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在“更喜欢组合而不是继承”时生成直通代码

在“更喜欢组合而不是继承”时生成直通代码
EN

Stack Overflow用户
提问于 2010-01-28 05:33:54
回答 4查看 3.4K关注 0票数 20

Problem

假设我正在尝试将一部手机建模为普通手机和PDA的组合。这是一种多继承的场景(手机就是一部手机,它是一部PDA)。由于C#不支持多重继承,这很可能需要某种组合。另外,假设我有其他的理由来支持构图。

我一直在想的是:有没有什么工具可以自动生成所有不可避免的直通代码?

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

接口:

代码语言:javascript
复制
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();
}

Implementations:

代码语言:javascript
复制
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 }
}

CellPhone类

代码语言:javascript
复制
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();
    }
}

编写CellPhone类既乏味又容易出错:

这个类真正做的就是充当PhonePda类的管道。确实没有理由需要人工来键入所有这些传递语句(如_phone.MakeCall(phoneNumber);)。它只是公开了几个成员字段的公共接口。

问题

  1. 有没有工具(最好是免费的:)可以让我从编写直通方法的单调乏味的错误中解脱出来?我知道我可以使用VS自动生成存根,但这只让我走了一半的路。
  2. 你能评价一下这种功能的可行性和可取性吗?是否值得向Microsoft建议添加这种类型的代码生成?如果我这么做了,你会给它加分吗?如果没有,你有什么反对意见?

编辑

似乎每个人都在说同样的话:为什么我不把_phone_pda变成公共属性呢?我反对这一点,因为它违反了“最低知识原则”。我的CellPhone类的客户端应该只做手机所做的事情,它不应该去处理哪些功能是Phone功能,哪些是Pda功能。这会创建额外的依赖项,并使CellPhone接口的功能不那么明显。

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

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-01-28 06:35:45

可以,您可以使用brilliant VS加载项ReSharper生成方法

从代码生成菜单中选择"generate delegating methods“选项(使用默认快捷方式方案按住Alt键并插入)。

如果您有一个实现接口的类,其中包含一个实现相同接口的字段,那么R#将为您提供生成直通代码的选项。它也可以与任何数量的接口一起工作。

票数 17
EN

Stack Overflow用户

发布于 2010-01-28 06:18:47

我以前见过这个建议(不一定在Stack Overflow上)。那是一段时间以前的事了。我相信作者制造了一个Connect问题,尽管我不知道它的状态。

建议的语法是以下语法之一:

代码语言:javascript
复制
public class CellPhone : IPhone, IPda
{
    private readonly IPhone _phone implements IPhone;
    private readonly IPda _pda : IPda;

    // ...
}
票数 2
EN

Stack Overflow用户

发布于 2017-01-11 23:15:25

在之前提供的答案中添加一些视觉效果和细节。

  1. 将接口添加到您希望成为包装类的类中

类MyWebElement : IWebElement { }

  1. 查找/单击"Delegate implementation“to a new field

  1. 选择您的选项

  1. 单击完成并享受您的新课程

类MyWebElement : IWebElement { IWebElement _webElementImplementation;public IWebElement FindElement(By @by) { return _webElementImplementation.FindElement( @by);} public ReadOnlyCollection FindElements(By @by){ return _webElementImplementation.FindElements(@by);} public void Clear() { _webElementImplementation.Clear();} public void SendKeys(string text) { _webElementImplementation.SendKeys(text);} public void Submit() { _webElementImplementation.Submit();} public void Click() { _webElementImplementation.Click();} public string GetAttribute(string attributeName) { return _webElementImplementation.GetAttribute(attributeName);} public string GetCssValue(string propertyName) { return _webElementImplementation.GetCssValue(propertyName);}公共字符串返回{ get { return _webElementImplementation.TagName;}}公共字符串文本{ get { return _webElementImplementation.Text;}}公共布尔已启用{ get { return _webElementImplementation.Enabled;}}已选择公共布尔{ get { return _webElementImplementation.Selected;}}}公共点位置{ get { return _webElementImplementation.Location;}}公共大小大小{ get { return _webElementImplementation.Size;}}显示的公共布尔值{ get { return _webElementImplementation.Displayed;}

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2150416

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档