C# 为什么我不能继承静态类?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/774181/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 00:37:34  来源:igfitidea点击:

Why can't I inherit static classes?

c#inheritancestatic

提问by User

I have several classes that do not really need any state. From the organizational point of view, I would like to put them into hierarchy.

我有几个真正不需要任何状态的类。从组织的角度来看,我想把它们分成层次结构。

But it seems I can't declare inheritance for static classes.

但似乎我不能为静态类声明继承。

Something like that:

类似的东西:

public static class Base
{
}

public static class Inherited : Base
{
}

will not work.

不管用。

Why have the designers of the language closed that possibility?

为什么语言的设计者关闭了这种可能性?

采纳答案by boj

Citation from here:

这里引用:

This is actually by design. There seems to be no good reason to inherit a static class. It has public static members that you can always access via the class name itself. The only reasons I have seen for inheriting static stuff have been bad ones, such as saving a couple of characters of typing.

There may be reason to consider mechanisms to bring static members directly into scope (and we will in fact consider this after the Orcas product cycle), but static class inheritance is not the way to go: It is the wrong mechanism to use, and works only for static members that happen to reside in a static class.

(Mads Torgersen, C# Language PM)

这实际上是设计使然。似乎没有充分的理由继承静态类。它具有公共静态成员,您始终可以通过类名本身访问这些成员。我所看到的继承静态内容的唯一原因是不好的,例如保存几个输入字符。

可能有理由考虑将静态成员直接引入作用域的机制(实际上我们将在 Orcas 产品周期之后考虑这一点),但静态类继承不是要走的路:这是使用错误的机制,并且有效仅适用于碰巧驻留在静态类中的静态成员。

(Mads Torgersen,C# 语言 PM)

Other opinions from channel9

来自channel9的其他意见

Inheritance in .NET works only on instance base.Static methods are defined on the type level not on the instance level. That is why overriding doesn't work with static methods/properties/events...

Static methods are only held once in memory. There is no virtual table etc. that is created for them.

If you invoke an instance method in .NET, you always give it the current instance. This is hidden by the .NET runtime, but it happens. Each instance method has as first argument a pointer (reference) to the object that the method is run on. This doesn't happen with static methods(as they are defined on type level). How should the compiler decide to select the method to invoke?

(littleguru)

.NET 中的继承仅适用于实例基础。静态方法是在类型级别而不是在实例级别定义的。这就是为什么覆盖不适用于静态方法/属性/事件......

静态方法只在内存中保存一次。没有为他们创建的虚拟表等。

如果在 .NET 中调用实例方法,则始终为其提供当前实例。这被 .NET 运行时隐藏,但它发生了。每个实例方法都有一个指向运行该方法的对象的指针(引用)作为第一个参数。静态方法不会发生这种情况(因为它们是在类型级别定义的)。编译器应该如何决定选择要调用的方法?

(小古鲁)

And as a valuable idea, littleguruhas a partial "workaround" for this issue: the Singletonpattern.

作为一个有价值的想法,littleguru为这个问题提供了部分“解决方法”:单例模式。

回答by CookieOfFortune

Hmmm... would it be much different if you just had non-static classes filled with static methods..?

嗯...如果你只是用静态方法填充非静态类会不会有很大不同......?

回答by Joel Coehoorn

Think about it this way: you access static members via type name, like this:

可以这样想:您可以通过类型名称访问静态成员,如下所示:

MyStaticType.MyStaticMember();

Were you to inherit from that class, you would have to access it via the new type name:

如果您从该类继承,则必须通过新类型名称访问它:

MyNewType.MyStaticMember();

Thus, the new item bears no relationships to the original when used in code. There would be no way to take advantage of any inheritance relationship for things like polymorphism.

因此,新项目在代码中使用时与原始项目没有任何关系。对于多态之类的东西,将无法利用任何继承关系。

Perhaps you're thinking you just want to extend some of the items in the original class. In that case, there's nothing preventing you from just using a member of the original in an entirely new type.

也许您认为您只想扩展原始类中的某些项目。在这种情况下,没有什么可以阻止您仅使用全新类型的原始成员。

Perhaps you want to add methods to an existing static type. You can do that already via extension methods.

也许您想向现有静态类型添加方法。您已经可以通过扩展方法来做到这一点。

Perhaps you want to be able to pass a static Typeto a function at runtime and call a method on that type, without knowing exactly what the method does. In that case, you can use an Interface.

也许您希望能够Type在运行时将静态传递给函数并调用该类型的方法,而无需确切知道该方法的作用。在这种情况下,您可以使用接口。

So, in the end you don't really gain anything from inheriting static classes.

所以,最终你并没有真正从继承静态类中获得任何好处。

回答by Andrew Hare

The main reason that you cannot inherit a static class is that they are abstract and sealed (this also prevents any instance of them from being created).

不能继承静态类的主要原因是它们是抽象的和密封的(这也阻止了它们的任何实例被创建)。

So this:

所以这:

static class Foo { }

compiles to this IL:

编译到这个 IL:

.class private abstract auto ansi sealed beforefieldinit Foo
  extends [mscorlib]System.Object
 {
 }

回答by Amit

What you want to achieve by using class hierarchy can be achieved merely through namespacing. So languages that support namespapces ( like C#) will have no use of implementing class hierarchy of static classes. Since you can not instantiate any of the classes, all you need is a hierarchical organization of class definitions which you can obtain through the use of namespaces

您想要通过使用类层次结构来实现的目标可以仅通过命名空间来实现。因此,支持命名空间的语言(如 C#)将不需要实现静态类的类层次结构。由于您无法实例化任何类,因此您只需要一个类定义的分层组织,您可以通过使用名称空间来获得它

回答by Lucas

Although you can access "inherited" static members through the inherited classes name, static members are not really inherited. This is in part why they can't be virtual or abstract and can't be overridden. In your example, if you declared a Base.Method(), the compiler will map a call to Inherited.Method() back to Base.Method() anyway. You might as well call Base.Method() explicitly. You can write a small test and see the result with Reflector.

尽管您可以通过继承的类名访问“继承的”静态成员,但静态成员并不是真正继承的。这就是为什么它们不能是虚拟的或抽象的,也不能被覆盖的部分原因。在您的示例中,如果您声明了 Base.Method(),编译器无论如何都会将对 Inherited.Method() 的调用映射回 Base.Method()。您也可以显式调用 Base.Method() 。您可以编写一个小测试并使用 Reflector 查看结果。

So... if you can't inherit static members, and if static classes can contain onlystatic members, what good would inheriting a static class do?

所以...如果你不能继承静态成员,如果静态类可以包含只有静态成员,将继承静态类有什么好处?

回答by Yogesh Karekar

You can use composition instead... this will allow you to access class objects from the static type. But still cant implements interfaces or abstract classes

您可以改用组合...这将允许您从静态类型访问类对象。但仍然无法实现接口或抽象类

回答by Zone

Static classes and class members are used to create data and functions that can be accessed without creating an instance of the class. Static class members can be used to separate data and behavior that is independent of any object identity: the data and functions do not change regardless of what happens to the object. Static classes can be used when there is no data or behavior in the class that depends on object identity.

静态类和类成员用于创建无需创建类的实例即可访问的数据和函数。静态类成员可用于分离独立于任何对象身份的数据和行为:无论对象发生什么,数据和函数都不会改变。当类中没有依赖于对象标识的数据或行为时,可以使用静态类。

A class can be declared static, which indicates that it contains only static members. It is not possible to use the new keyword to create instances of a static class. Static classes are loaded automatically by the .NET Framework common language runtime (CLR) when the program or namespace that contains the class is loaded.

一个类可以声明为静态的,这表明它只包含静态成员。不能使用 new 关键字来创建静态类的实例。加载包含类的程序或命名空间时,.NET Framework 公共语言运行时 (CLR) 会自动加载静态类。

Use a static class to contain methods that are not associated with a particular object. For example, it is a common requirement to create a set of methods that do not act on instance data and are not associated to a specific object in your code. You could use a static class to hold those methods.

使用静态类来包含与特定对象无关的方法。例如,创建一组不作用于实例数据且不与代码中的特定对象关联的方法是一个常见的要求。您可以使用静态类来保存这些方法。

Following are the main features of a static class:

以下是静态类的主要功能:

  1. They only contain static members.

  2. They cannot be instantiated.

  3. They are sealed.

  4. They cannot contain Instance Constructors (C# Programming Guide).

  1. 它们只包含静态成员。

  2. 它们不能被实例化。

  3. 它们是密封的。

  4. 它们不能包含实例构造函数(C# 编程指南)。

Creating a static class is therefore basically the same as creating a class that contains only static members and a private constructor. A private constructor prevents the class from being instantiated.

因此,创建静态类与创建仅包含静态成员和私有构造函数的类基本相同。私有构造函数可防止类被实例化。

The advantage of using a static class is that the compiler can check to make sure that no instance members are accidentally added. The compiler will guarantee that instances of this class cannot be created.

使用静态类的优点是编译器可以检查以确保没有意外添加实例成员。编译器将保证无法创建此类的实例。

Static classes are sealed and therefore cannot be inherited. They cannot inherit from any class except Object. Static classes cannot contain an instance constructor; however, they can have a static constructor. For more information, see Static Constructors (C# Programming Guide).

静态类是密封的,因此不能被继承。它们不能从除 Object 之外的任何类继承。静态类不能包含实例构造函数;但是,它们可以有一个静态构造函数。有关更多信息,请参阅静态构造函数(C# 编程指南)。

回答by Soumen Chakraborty

When we create a static class that contains only the static members and a private constructor.The only reason is that the static constructor prevent the class from being instantiated for that we can not inherit a static class .The only way to access the member of the static class by using the class name itself.Try to inherit a static class is not a good idea.

当我们创建一个只包含静态成员和一个私有构造函数的静态类时。唯一的原因是静态构造函数阻止类被实例化,因为我们不能继承静态类。访问成员的唯一方法静态类通过使用类名本身。尝试继承静态类不是一个好主意。

回答by Konard

You can do something that will look like static inheritance.

你可以做一些看起来像静态继承的事情。

Here is the trick:

这是诀窍:

public abstract class StaticBase<TSuccessor>
    where TSuccessor : StaticBase<TSuccessor>, new()
{
    protected static readonly TSuccessor Instance = new TSuccessor();
}

Then you can do this:

然后你可以这样做:

public class Base : StaticBase<Base>
{
    public Base()
    {
    }

    public void MethodA()
    {
    }
}

public class Inherited : Base
{
    private Inherited()
    {
    }

    public new static void MethodA()
    {
        Instance.MethodA();
    }
}

The Inheritedclass is not static itself, but we don't allow to create it. It actually has inherited static constructor which builds Base, and all properties and methods of Baseavailable as static. Now the only thing left to do make static wrappers for each method and property you need to expose to your static context.

Inherited班是不是静态的本身,但我们不允许创建它。它实际上继承了构建的静态构造函数Base,以及所有Base可用的静态属性和方法。现在唯一要做的就是为您需要向静态上下文公开的每个方法和属性制作静态包装器。

There are downsides like the need for manual creation of static wrapper methods and newkeyword. But this approach helps support something that is really similar to static inheritance.

有一些缺点,比如需要手动创建静态包装方法和new关键字。但是这种方法有助于支持与静态继承非常相似的东西。

P.S. We used this for creating compiled queries, and this actually can be replaced with ConcurrentDictionary, but a static read-only field with its thread safety was good enough.

PS 我们用它来创建编译查询,这实际上可以用 ConcurrentDictionary 代替,但是具有线程安全性的静态只读字段就足够了。