C#静态成员"继承和QUOT; - 为什么会发生这种存在呢? [英] C# static member "inheritance" - why does this exist at all?

查看:100
本文介绍了C#静态成员"继承和QUOT; - 为什么会发生这种存在呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C#中,一个父类的静态成员被继承到子类范围。例如:

  A类{公共静态INT M(){返回1; }}
B类:A {}
C类:A {公众新的静态INT M(){返回2; }}
[...]
上午(); //返回1
B.M(); //返回1 - 这相当于A.M()
厘米(); //返回2 - 这不等同于A.M()

现在,你不能继承静态类,唯一的地方,我可以想像,静态继承关系可能会忽略它,完全是:虽然可以让一个需要类型参数 T A ,你仍然不能称之为 TM()(这可能是简化了的东西对于VM),更不用说写在子类中不同的 M 的实施和使用。

因此​​,静态成员的继承只是看起来像命名空间的污染;即使你明确限定名称(即 B.M A 的版本仍然解决。

修改与命名空间比较:

 命名空间N1 {类X(); }
命名空间N1.N2 {类X(); }
命名空间N1.N2.N3 {[...]}

N1.N2.N3 这是有道理的,如果我用 X 没有它指的是<$资格C $ C> N1.N2.X 。但是,如果我明确提及 N1.N2.N3.X - 并没有这样的类存在 - 我不希望它找到 N2 的版本;如果你试试这个确实是编译器报告错误。相反,如果我明确地提及 B.M(),为什么不编译器报告的错误?毕竟,没有M方法B......

这是否继承有什么目的?可以将此功能进行建设性的莫名其妙使用?


解决方案

  

因此​​,静态继承
  会员只是看起来像命名空间
  污染


这是正确的,但一个人的污染是另一个人的加入辛辣调味品。

我认为马丁福勒,在其上的DSL工作,已使用继承以这种方式,以允许静态方法方便地访问的建议,允许在不类名称限定要使用的那些方法。因此调用code必须在继承中被定义的方法类的类。 (我认为这是一个烂主意。)

在我看来,静态成员不应混为一谈与非静态目的的一类,你在这里提出这个问题是为什么不将它们混合很重要的原因之一。

隐藏私有静态的原本instancey类的实现内部可变的数据尤为可怕。但随后有静态方法,这是更糟糕的混频器。下面是一个典型的使用静态方法混合成一个类:

 公共类的事
{
    //典型的每个实例的东西
    诠释_member1;
    受保护的虚拟无效美孚(){...}
    公共无效栏(){...}    //工厂方法
    公共静态的东西制作()
    {
        返回新事物();
    }
}

这是静态工厂方法模式。这是毫无意义的大部分时间,但更糟糕的是,现在我们有这样的:

 公共类AnotherThing:事情{}

这现在有一个静态制作方法返回一个的事情,而不是 AnotherThing

这种不匹配的强烈暗示与静态方法有什么要密封。静态成员不具有继承集成。这是没有意义让他们遗传的。所以我一直一成不变的东西在不同的静态类,我发牢骚有冗余时,我已经说过,这个类是静态声明的每一个成员是静态的。

但是,这只是其中的过晚,现在的事情之一。所有真实的,工作语言(库及产品)有几个人。 C#有几个显着。

In C#, a superclass's static members are "inherited" into the subclasses scope. For instance:

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()

Now, you can't inherit static classes, and the only place I can imagine that static inheritance might matter ignores it entirely: although you can make a generic constraint that requires a type parameter T to be a subclass of A, you still cannot call T.M() (which probably simplifies things for the VM), let alone write a different M implementation in a subclass and use that.

So, the "inheritance" of static members merely looks like namespace pollution; even if you explicitly qualify the name (i.e. B.M) A's version is still resolved.

Edit compare with namespaces:

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

Within N1.N2.N3 It makes sense that if I use X without qualification it refers to N1.N2.X. But if I explicitly refer to N1.N2.N3.X - and no such class exists - I don't expect it to find N2's version; and indeed to compiler reports an error if you try this. By contrast, if I explicitly refer to B.M(), why doesn't the compiler report an error? After all, there's no "M" method in "B"...

What purpose does this inheritance have? Can this feature be used constructively somehow?

解决方案

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

That's right, except that one guy's pollution is another guy's added spicy flavouring.

I think Martin Fowler, in his work on DSLs, has suggested using inheritance in this way to allow convenient access to static methods, allowing those methods to be used without class name qualification. So the calling code has to be in a class that inherits the class in which the methods are defined. (I think it's a rotten idea.)

In my opinion, static members should not be mixed into a class with a non-static purpose, and the issue you raise here is part of the reason why it's important not to mix them.

Hiding private static mutable data inside the implementation of an otherwise "instancey" class is particularly horrible. But then there are static methods, which are even worse mixers. Here's a typical use of static methods mixed into a class:

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();
    }
}

It's the static factory method pattern. It's pointless most of the time, but even worse is that now we have this:

public class AnotherThing : Thing { }

This now has a static Make method which returns a Thing, not a AnotherThing.

This kind of mismatch strongly implies that anything with static methods should be sealed. Static members fail to integrate well with inheritance. It makes no sense to have them heritable. So I keep static things in separate static classes, and I gripe about redundantly having to declare every member static when I've already said that the class is static.

But it's just one of those too-late-now things. All real, working languages (and libraries, and products) have a few of them. C# has remarkably few.

这篇关于C#静态成员&QUOT;继承和QUOT; - 为什么会发生这种存在呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆