使用方法的默认类版本的C#Decorator类

使用方法的默认类版本的C#Decorator类,c#,design-patterns,webdriver,decorator,C#,Design Patterns,Webdriver,Decorator,如果试图修饰一个类,如何使方法与默认实现保持一致 例如,我试图向WebDriver类的IWebDriver接口添加一个属性 i、 e Visual Studio IntelliSense让我用一堆“抛出新的NotImplementedException()”来实现类(或接口)作为默认WebDriver类方法的方法体 i、 e 我的问题是,如果我根本不想调整这些方法的行为,我该如何实现?我是将其全部保留在正文中的那一行,还是必须这样做(例如,如果是这种情况,那么对于带有返回类型和参数的FindEl

如果试图修饰一个类,如何使方法与默认实现保持一致

例如,我试图向WebDriver类的IWebDriver接口添加一个属性

i、 e

Visual Studio IntelliSense让我用一堆“
抛出新的NotImplementedException()”来实现类(或接口)
作为默认WebDriver类方法的方法体

i、 e

我的问题是,如果我根本不想调整这些方法的行为,我该如何实现?我是将其全部保留在正文中的那一行,还是必须这样做(例如,如果是这种情况,那么对于带有返回类型和参数的FindElement方法,该如何做?):

公共字符串CurrentWindowHandle
{
得到
{
返回_driver.CurrentWindowHandle;
}
}
公共只读集合窗口句柄
{
得到
{
返回_driver.WindowHandles;
}
}
公众假期结束()
{
_driver.Close();
}
公开作废退出()
{
_driver.Quit();
}
我只是尝试向IWebDriver接口添加一个字符串变量,以跟踪正在运行的测试

编辑:我找到了一个解决我最初问题的替代方案(正确记录测试结果),它不涉及实现任何新功能,而是将try/catch放在正确的位置

这个问题的解决方案可以在标记的答案中找到,下面@AlexanderWinter展示了一个实现示例,其中包括一种全局检索数据的方法


感谢您的帮助。

查看向函数添加功能而不是围绕整个类创建包装的步骤

查看向函数添加功能而不是围绕整个类创建包装的步骤

IWebDriver没有默认行为,它根本没有行为,因为它是一个接口

接口没有内容,只有方法和事件原型。您想要的是继承实现此接口的类。因此,在已经实现的情况下,您可以编辑该类。如果继承的是类,则只能重写所需的方法,甚至可以使用base.callToBaseMethod()调用基方法

这里有一个例子

public interface IAnimal //this has no behavior at all, it's an interface
{
    void eat();
    string Name { get; }
}

public class Animal //this has a behavior you can modify
{
    private string m_name;

    public Animal(string name)
    {
        this.m_name = name;
    }

    public void eat()
    {
        Console.WriteLine(m_name + " is eating !");
    }

    public string Name
    {
        get { return m_name; }
    }
}

public class Cat : Animal //this is your class that changes the behavior 
{                         //of the Animal class
    public Cat(string name) : base("Cat " + name) //we always need to call 
    { }                                           //a base constructor

    public override void eat() //here we are overriding the eat method
    {
        base.eat(); //calling the Animal eat method
        Console.WriteLine("He is eating fish !"); //editing the methd a bit
    }

    //no need to change the behavior of the Name property so we do nothing here
}
因此,找到具有您所讨论的默认行为的类,并继承该类

希望能有帮助

根据OP的需要进行编辑:

对于密封类,您不能使用此解决方案编辑该类。这是密封类的要点,但C#有扩展方法

galenus的解决方案很好,但是请求从应用程序中的某个地方进行额外调用可能会让类用户感到困惑。您可以混合使用扩展方法和外部字典来对额外属性进行完整的模拟。但是,由于C#中不存在扩展属性,因此必须创建GetProperty和SetProperty等方法

下面是一个例子:

/// <summary>
/// An extension from the sealed StringBuilder class that saves 
/// a color with a StringBuilder !
/// </summary>
public static class StringBuilderExt
{
    private static readonly Dictionary<StringBuilder, Color> colors = new Dictionary<StringBuilder, Color>();

    public static void SetColor(this StringBuilder builder, Color color)
    {
        colors[builder] = color;
    }

    public static Color GetColor(this StringBuilder builder)
    {
        if(colors.ContainsKey(builder))
        {
            return colors[builder];
        }

        return Color.Black;
   }
}
但这只是一个解决办法,可能还有更好的办法。试试看,选择最适合你需要的


希望这样做

IWebDriver没有默认行为,它根本没有行为,因为它是一个接口

接口没有内容,只有方法和事件原型。您想要的是继承实现此接口的类。因此,在已经实现的情况下,您可以编辑该类。如果继承的是类,则只能重写所需的方法,甚至可以使用base.callToBaseMethod()调用基方法

这里有一个例子

public interface IAnimal //this has no behavior at all, it's an interface
{
    void eat();
    string Name { get; }
}

public class Animal //this has a behavior you can modify
{
    private string m_name;

    public Animal(string name)
    {
        this.m_name = name;
    }

    public void eat()
    {
        Console.WriteLine(m_name + " is eating !");
    }

    public string Name
    {
        get { return m_name; }
    }
}

public class Cat : Animal //this is your class that changes the behavior 
{                         //of the Animal class
    public Cat(string name) : base("Cat " + name) //we always need to call 
    { }                                           //a base constructor

    public override void eat() //here we are overriding the eat method
    {
        base.eat(); //calling the Animal eat method
        Console.WriteLine("He is eating fish !"); //editing the methd a bit
    }

    //no need to change the behavior of the Name property so we do nothing here
}
因此,找到具有您所讨论的默认行为的类,并继承该类

希望能有帮助

根据OP的需要进行编辑:

对于密封类,您不能使用此解决方案编辑该类。这是密封类的要点,但C#有扩展方法

galenus的解决方案很好,但是请求从应用程序中的某个地方进行额外调用可能会让类用户感到困惑。您可以混合使用扩展方法和外部字典来对额外属性进行完整的模拟。但是,由于C#中不存在扩展属性,因此必须创建GetProperty和SetProperty等方法

下面是一个例子:

/// <summary>
/// An extension from the sealed StringBuilder class that saves 
/// a color with a StringBuilder !
/// </summary>
public static class StringBuilderExt
{
    private static readonly Dictionary<StringBuilder, Color> colors = new Dictionary<StringBuilder, Color>();

    public static void SetColor(this StringBuilder builder, Color color)
    {
        colors[builder] = color;
    }

    public static Color GetColor(this StringBuilder builder)
    {
        if(colors.ContainsKey(builder))
        {
            return colors[builder];
        }

        return Color.Black;
   }
}
但这只是一个解决办法,可能还有更好的办法。试试看,选择最适合你需要的


希望这样做

而不是扩展类,使用外部方法保存数据。你可以使用的东西是

您可以通过以下方式使用它:

class TestState
{
    public string Name { get; set; }
}

//initialization of some private field
ConditionalWeakTable<IWebDriver, TestState> myTestsByDriver = new ConditionalWeakTable<IWebDriver, TestState>();

...

//usage:
myTestsByDriver.GetOrCreateValue().Name = "My_First_Test";
//etc.
类TestState
{
公共字符串名称{get;set;}
}
//某些私有字段的初始化
ConditionalWeakTable myTestsByDriver=新的ConditionalWeakTable();
...
//用法:
myTestsByDriver.GetOrCreateValue().Name=“我的第一次测试”;
//等等。

使用外部方法保存数据,而不是扩展类。你可以使用的东西是

您可以通过以下方式使用它:

class TestState
{
    public string Name { get; set; }
}

//initialization of some private field
ConditionalWeakTable<IWebDriver, TestState> myTestsByDriver = new ConditionalWeakTable<IWebDriver, TestState>();

...

//usage:
myTestsByDriver.GetOrCreateValue().Name = "My_First_Test";
//etc.
类TestState
{
公共字符串名称{get;set;}
}
//某些私有字段的初始化
ConditionalWeakTable myTestsByDriver=新的ConditionalWeakTable();
...
//用法:
myTestsByDriver.GetOrCreateValue().Name=“我的第一次测试”;
//等等。

我只想向类中添加一个成员,不一定要扩展任何功能。只是想知道如何让函数保持其基本状态。为什么不创建一个包含所需成员和
IWebDriver
的结构,然后像
myStruct.myMember
myStruct.WebDriver.AnyMethod
一样访问它呢?或者在另一个变量中跟踪字符串,而不是以这种方式?在我看来,一项简单的任务过于复杂了,但我不知道你的最终目标是什么。我在考虑这一点,但要实现我当前的项目需要进行一次大的改革,因为目前所有的事情都通过WebDriver实例来实现
class TestState
{
    public string Name { get; set; }
}

//initialization of some private field
ConditionalWeakTable<IWebDriver, TestState> myTestsByDriver = new ConditionalWeakTable<IWebDriver, TestState>();

...

//usage:
myTestsByDriver.GetOrCreateValue().Name = "My_First_Test";
//etc.