C# 静态成员 "inheritance"- 为什么它存在?

标签 c# inheritance static language-design

在 C# 中,父类(super class)的静态成员被“继承”到子类范围中。例如:

class A { public static int M() { return 1; } }
class B : A {}
class C : A { public new static int M() { return 2; } }
[...]
A.M(); //returns 1
B.M(); //returns 1 - this is equivalent to A.M()
C.M(); //returns 2 - this is not equivalent to A.M()

现在,你不能继承静态类,而我唯一能想到静态继承可能很重要的地方完全忽略了它:尽管你可以创建一个需要类型参数 T 的通用约束是 A 的子类,您仍然不能调用 T.M()(这可能简化了 VM 的事情),更不用说编写不同的 M在子类中实现并使用它。

因此,静态成员的“继承”只是看起来像 namespace 污染;即使您明确限定名称(即 B.M),A 的版本仍会得到解析。

编辑与命名空间比较:

namespace N1{  class X();   }
namespace N1.N2 {  class X();   }
namespace N1.N2.N3 { [...] }

N1.N2.N3 中 如果我在没有限定的情况下使用 X,它指的是 N1.N2.X,这是有道理的。但是如果我明确引用 N1.N2.N3.X - 并且不存在这样的类 - 我不希望它找到 N2 的版本;如果您尝试这样做,编译器确实会报告错误。相反,如果我明确引用 B.M(),为什么编译器不报告错误?毕竟,“B”中没有“M”方法……

这种继承的目的是什么?能否以某种方式建设性地使用此功能?

最佳答案

So, the "inheritance" of static members merely looks like namespace pollution

没错,只是一个人的污染是另一个人添加的辛辣调味剂。

我认为 Martin Fowler 在他关于 DSL 的工作中建议以这种方式使用继承以允许方便地访问静态方法,允许在没有类名限定的情况下使用这些方法。因此,调用代码必须位于继承定义方法的类的类中。 (我认为这是一个烂主意。)

在我看来,不应将静态成员混合到具有非静态目的的类中,您在此处提出的问题是不混合它们很重要的部分原因。

将私有(private)静态可变数据隐藏在一个“实例化”类的实现中尤其可怕。但是还有静态方法,这是更糟糕的混合器。下面是混合到类中的静态方法的典型用法:

public class Thing
{
    // typical per-instance stuff
    int _member1;
    protected virtual void Foo() { ... }
    public void Bar() { ... }

    // factory method
    public static Thing Make()
    {
        return new Thing();
    }
}

这是静态工厂方法模式。大多数时候这是毫无意义的,但更糟糕的是现在我们有了这个:

public class AnotherThing : Thing { }

这现在有一个静态的 Make 方法,它返回一个 Thing,而不是 AnotherThing

这种不匹配强烈暗示任何带有静态方法的东西都应该被密封。静态成员无法很好地与继承集成。让它们可遗传是没有意义的。因此,我将静态内容保存在单独的静态类中,并且在我已经说过该类是静态的情况下,我提示不得不将每个成员都声明为静态的。

但这只是那些为时已晚的事情之一。所有真实的工作语言(以及图书馆和产品)都有其中的一些。 C# 非常少。

关于C# 静态成员 "inheritance"- 为什么它存在?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2281775/

相关文章:

c++ - C++ 中的静态构造函数和 fatal error LNK1120 : 1 unresolved externals

c# - TreeView 验证

c# - 删除可选的最后一个括号

c# - 方法参数的数量可变,每个参数的类型不同

java - .NET AES 加密和 Android 解密

c++ - V8 继承的 FunctionTemplate 没有得到对父 FunctionTemplate 的更新

java - 关于依赖共享的 Maven 多模块项目组合

c++:多态+多重继承顺序。继承顺序重要吗?

c - 静态函数和普通函数中的变量

c++ - 递归函数中的boost regex smatch表现得像一个静态变量