【问题标题】:public static method + interface公共静态方法+接口
【发布时间】:2014-02-20 11:39:21
【问题描述】:

既然我们不能在接口中定义公共静态方法,那么这样的接口可以在具有公共静态的类中实现吗?

public interface IValidator
{
    bool IsValid(bool data);
}

public class MyValidator : IValidator
{
    public static bool IsValid(string data)
    {
        //code which returns bool
    }
}

【问题讨论】:

  • 接口是一种利用多态性的方法。静态成员不参与多态性。
  • 如果你必须使用接口来定义这样的行为,你有两种选择,单例或扩展方法。

标签: c# interface static


【解决方案1】:

不,C# 不允许使用静态接口。

接口被设计成类之间的契约,契约定义了这些类的每个实例都有一组方法。

Jon Skeet 在this question 中给出了很好的解释,我推荐阅读它。

【讨论】:

  • 考虑使用单例设计模式和非静态方法。这可能适用于您的情况。
【解决方案2】:

当您有一个对象实例时,将其转换并用作接口是有意义的。但是当你使用静态的东西时,情况就不是这样了。您只能通过包含类的名称访问静态成员,不能像实例一样传递它们。

可以实现一个接口并确保它不会被多次实例化,这称为单例模式。单例类类似于静态类,但它有一个可以传递的实例,也可以实现接口。

【讨论】:

    【解决方案3】:

    不,但是您可以通过让静态成员返回接口的实例来获得接近它的东西。
    有点像:

    public class MyValidator : IValidator
    {
        public bool IsValid(string data)
        {
            //code which returns bool
        }
    
        public static readonly IValidator Instance = new MyValidator();
    }
    

    然后您可以以静态方式使用它:

    bool isValid = MyValidator.Instance.IsValid("data");
    

    【讨论】:

    • 使其成为具有私有支持字段的公共属性。
    • @dcastro,是的,你可以做到。在 Stack Overflow 上,我总是尝试编写最少量的独立工作代码;只是问或回答问题。我认为额外的代码只会让人更难看出哪一点真正回答了问题。
    【解决方案4】:

    您不能通过接口定义静态成员,因此如果设计需要静态成员,则只能将它们添加到具体类型中。

    这最终会产生很多混乱。任何其他实现都不会具有相同的成员。模拟实例将无权访问该成员。以此类推。

    解决方案是避免声明静态成员。在您的特定情况下,我会反对界面的设计。我希望看到类实现一些接口,如 IValidatable:

    public interface IValidatable
    {
        bool IsValid();
    }
    ...
    public class SomeBoolClass: IValidatable
    {
        private bool Data;
        public bool IsValid()
        {
            return this.Data; // i.e. return Data == true
        }
    }
    ...
    public class SomeStringClass: IValidatable
    {
        private string Data;
        public bool IsValid()
        {
            return !string.IsNullOrEmpty(this.Data);
        }
    }
    

    通过这种方式,您可以获得跨所有当前和未来类型的完全多态验证。

    如果你坚持要有一个接收低级数据(如布尔值或字符串)的验证器来验证,那么你就半途而废了。假设有两个包装字符串数据的类。这两个类通常必须以不同的方式进行验证。但是验证器将无法根据输入数据区分应用哪种验证算法。更糟糕的是,验证器必须包含所有类型的所有验证逻辑,现有的和尚未编码的。这意味着验证器将充当一个巨大的(并且本质上是不完整的)switch 语句。

    【讨论】:

      猜你喜欢
      • 2023-03-26
      • 2011-04-19
      • 1970-01-01
      • 2012-02-11
      • 2011-05-04
      • 2013-07-22
      • 2017-06-08
      • 2015-02-10
      • 1970-01-01
      相关资源
      最近更新 更多