Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 构造函数重构中的虚拟方法调用_C#_Oop_Refactoring_Virtual Functions - Fatal编程技术网

C# 构造函数重构中的虚拟方法调用

C# 构造函数重构中的虚拟方法调用,c#,oop,refactoring,virtual-functions,C#,Oop,Refactoring,Virtual Functions,我有一个Client类,它接受构造函数中带有IConfiguration接口的对象 创建客户端对象时,应验证配置 public interface IConfiguration { int ReconnectDelay { get; } } public class Client { public Client(IConfiguration configuration) { if (configuration.ReconnectDelay < 60

我有一个
Client
类,它接受构造函数中带有
IConfiguration
接口的对象

创建
客户端
对象时,应验证配置

public interface IConfiguration
{
    int ReconnectDelay { get; }
}

public class Client
{
    public Client(IConfiguration configuration)
    {
        if (configuration.ReconnectDelay < 60000)
        {
            throw new ConfigurationErrorsException();
        }
    }
}
它可以工作,但会导致调用构造函数中的虚方法,这是不好的(我知道现在它不会有什么坏处,但我还是想解决这个问题)


那么,有什么优雅的解决方案吗?

您可以创建一个包含2个实现的验证器接口,然后委托给验证器。从技术上讲,这仍然是一个虚拟调用,但它指向另一个对象,因此您不必担心
Client
的子类会覆盖调用或访问部分构建的客户端

public interface IValidator
{
    bool Validate (IConfiguration configuration);
}
然后,您的正常用例使用重新连接验证器

public class ReconnectionValidator : IValidator
{

     bool Validate (IConfiguration configuration)
     {
       return configuration.ReconnectDelay >= 60000;
     }
}
您的测试验证器始终可以返回true

public class NullValidator : IValidator
{

     bool Validate (IConfiguration configuration)
     {
       return true;
     }
}
然后,您的客户端代码将在其构造函数中同时获取
IValidator
IConfiguration
,并测试验证器是否验证了配置

public Client(IConfiguration configuration, IValidator validator)
{
   if(!validator.Validate(configuration))
   {
        throw new ConfigurationErrorsException();
    }
}

这种技术的好处是,您可以在以后更改验证器,或者使用一个新的实现将多个验证器链接在一起,以支持“或”ing和“and”验证器。

您可以将类
TestClient
密封起来吗?@Dmitry这会有什么帮助?诚实的问题。@Dmitry,我可以将
TestClient
密封起来,但这里的问题是
Client
类。谢谢,我喜欢你的解决方案。@bniwredyc太好了。我刚刚修复了我的重新连接验证器代码中的一个输入错误,该错误可能会失败,因为我的布尔逻辑是反向的
public Client(IConfiguration configuration, IValidator validator)
{
   if(!validator.Validate(configuration))
   {
        throw new ConfigurationErrorsException();
    }
}