C# 是否可以将专用方法添加到实现特定接口的类中?

C# 是否可以将专用方法添加到实现特定接口的类中?,c#,inheritance,extension-methods,C#,Inheritance,Extension Methods,我在一个使用Google协议缓冲区的自动化平台上工作,协议服务的C#实现继承自生成的基类 每个服务都表示页面的一部分以及可以在该页面上执行的操作,因此将有多个服务表示类似的操作,即任何基于选项卡的界面部分 在其中一个服务的实现中,我有一些实用程序代码,用于处理选项卡之间的导航以及等待加载选项卡 我想做的是向实现中添加一个接口(可能是一个空接口),对于继承该接口的任何类,都可以访问实用程序代码 一些代码来说明我所要寻找的配置,这些代码不是一个精确的实现,只是一个超级简化的版本来阐明这一点: pub

我在一个使用Google协议缓冲区的自动化平台上工作,协议服务的C#实现继承自生成的基类

每个服务都表示页面的一部分以及可以在该页面上执行的操作,因此将有多个服务表示类似的操作,即任何基于选项卡的界面部分

在其中一个服务的实现中,我有一些实用程序代码,用于处理选项卡之间的导航以及等待加载选项卡

我想做的是向实现中添加一个接口(可能是一个空接口),对于继承该接口的任何类,都可以访问实用程序代码

一些代码来说明我所要寻找的配置,这些代码不是一个精确的实现,只是一个超级简化的版本来阐明这一点:

public class TabWindowServiceImpl : AbstractTabWindowService, ITabNavigation
{
    public ActionResult NavigateToTab1()
    {
        return TryNavigateToTab("tab1");
    }

    public ActionResult NavigateToTab2()
    {
        return TryNavigateToTab("tab2");
    }
}

public interface ITabNavigation
{}

// This is an example of a function I would like to add to the ITabNavigation Interface

public ActionResult TryNavigateToTab(string tabId, string tabLoadedElementId)
{
    try
    {
        //Driver is a static singelton
        Driver.FindElement(tabId).Click();
        Driver.WaitUntilPresent(tabLoadedElementId);
    }
    catch (Exception ex)
    {
        return new FailureActionResult(ex.Message);
    }
}

最后请注意,TryNavigateToTab方法理想情况下不应在选项卡WindowsServiceImpl上公开,只能私下使用。

我假设您的内部意思是“在程序集中”。只需引入另一个带有modifier
internal
的界面

internal interface ITabNavigationInternal : ITabNavigation
{
    ActionResult TryNavigateToTab(string tabId, string tabLoadedElementId);
}
然后您必须使用“显式接口实现”来实现它,这样您就不能在没有接口实例的情况下访问该方法,这样就不会公开该方法,因为接口本身
内部

public class TabWindowServiceImpl : AbstractTabWindowService, ITabNavigation, ITabNavigationInternal 
{
    ActionResult ITabNavigationInternal.TryNavigateToTab(string tabId, string tabLoadedElementId)
    {
       //Your implementation here.
    }
}
用例:

ITabNavigationInternal instance = new TabWindowServiceImpl();
var res =instance.TryNavigateToTab(tabId, tabLoadedElementId); 
注意:这仍然可以通过
反射
动态
访问,但不能通过类的实例直接访问


很抱歉,如果这无法编译或没有帮助,我还没有进行测试。

如果我理解正确,您正在尝试向实现特定接口的类添加实用工具方法,但没有向接口的普通用户公开这些方法

好吧,这是不可能的,事实上也没什么意义。您真正应该使用的是带有实用程序方法的静态类。大概是这样的:

public static class Utilities
{
    public static ActionResult TryNavigateToTab(string tabId, string tabLoadedElementId)
    {
        try
        {
            //Driver is a static singelton
            Driver.FindElement(tabId).Click();
            Driver.WaitUntilPresent(tabLoadedElementId);
                    // TODO return something
        }
        catch (Exception ex)
        {
            return new FailureActionResult(ex.Message);
        }
    }
}
希望使用这些方法的类可以这样使用它们(不需要接口):

但是,如果您真的想“添加神奇的方法”,您可以通过在隐藏名称空间中的类上将方法转换为扩展方法来获得类似的结果:

namespace Something.Something.Helpers
{
    public static class Utilities
    {
        public static ActionResult TryNavigateToTab(this ITabNavigation self,
                                             string tabId,
                                             string tabLoadedElementId)
        {
            try
            {
                //Driver is a static singelton
                Driver.FindElement(tabId).Click();
                Driver.WaitUntilPresent(tabLoadedElementId);
                            // TODO: return something
            }
            catch (Exception ex)
            {
                return new FailureActionResult(ex.Message);
            }
        }
    }
}
然后,在使用接口的任何代码中,确保包含名称空间并使用前缀为this的方法。:

using Something.Something.Helpers;
...
public ActionResult NavigateToTab1()
{
    return this.TryNavigateToTab("tab1");
}

我已经澄清了我的问题,理想情况下,我希望它是类的内部(即private),这样在使用tabWindowsServiceImpl时,您只能看到NavigateTab1和NavigateTab2,它们实际上都使用TryNavigateToTab.AFAIK,这是不可能的,您必须使用标准方法。即使在语言允许的情况下,我也认为没有必要将其添加到界面中作为
private
。这只是供您使用,还是供其他也实现该界面的用户使用?该平台最终将由多个团队使用,这就是为什么我关心公开实用工具方法的原因。摘要(适用于未来的用户):您是否可以将受保护的
方法添加到
界面
。回答:不,不是真的;但是你可以把它隐藏在一个名称空间后面。是的,我在想这是不可能的,我不想使用一个实用程序类,只是想把它锁定为只在应该能够使用它的类型中使用。谢谢你的洞察力。
using Something.Something.Helpers;
...
public ActionResult NavigateToTab1()
{
    return this.TryNavigateToTab("tab1");
}