【问题标题】:How can a static class derive from an object?静态类如何从对象派生?
【发布时间】:2010-10-08 01:24:03
【问题描述】:

我正在尝试通过静态类继承非静态类。

public class foo
{ }

public static class bar : foo
{ }

我得到:

静态类不能从类型派生。 静态类必须派生自 对象。

如何从对象派生它?

代码在 C# 中。

【问题讨论】:

  • 这个有用例吗?

标签: c# oop


【解决方案1】:

OP 询问“我怎样才能从对象中驱动它?”。 object 这里不是另一个类的实例,所以答案是你没有。 object 指的是 System.Object 基类,它是 .NET 中所有类型的默认基类。错误信息有点误导。

为了完整起见,另一方面,静态类也不能被继承或扩展,因为它既是抽象类又是密封类。

【讨论】:

    【解决方案2】:

    正如 Christopher 所指出的,假设我们可以从非静态类派生静态类。

    例如:

    public class foo
    {
        public int myVar;
    }
    
    public static class bar : foo { }
    

    这里,bar 类派生自 foo,因此静态类 Bar 现在具有非静态成员 myVar ,并且根据c#规范,静态类不能包含非静态成员!

    【讨论】:

      【解决方案3】:

      派生静态类没有任何价值。使用继承的原因是:

      • 多态性
      • 代码重用

      显然,您不能使用静态类获得多态性,因为没有实例可以动态调度(换句话说,您不能将 Bar 传递给期望 Foo 的函数,因为您不 有一个酒吧)。

      使用组合很容易解决代码重用:给 Bar 一个 Foo 的静态实例。

      【讨论】:

      • +1 为 OP 的问题提供简单而适当的解决方案。
      • 对不起“线程挖掘”,但我想做同样的事情,虽然我认为你的回答很好,但我想知道你将如何处理 foo 的用例有一些 bar 想使用的受保护方法。
      • 你是说你想要一个继承自 non-static Foostatic Bar 类,以便它可以访问它的受保护成员?这种设计有很多问题(很少有单个类在静态和非静态上下文中都有意义)。但是,假设您对此有正当理由,一种解决方案是让Bar 拥有一个继承自Foo 的私有内部非静态类(称为FooWrapper)。它具有转发给它继承的受保护方法的公共方法。然后Bar 可以拥有FooHelper 的实例并通过它访问Foo 中的受保护成员。
      • 你可以使用单例模式来实现继承和静态(ish)行为
      • 派生的另一个用途是为通用参数提供默认参数。如本问题所示,C# 不支持默认值,但您可以通过覆盖来解决此问题。 stackoverflow.com/questions/2747874/default-for-generic-type 公共静态类 ActionInvoker : ActionInvoker { } 公共静态类 ActionInvoker { }
      【解决方案4】:

      正如在其他答案中所说,编译器消息令人困惑但正确。你可以写:

      static class A : object
      {
      }
      

      当然,显式声明这种继承并不是很有用,但是当您覆盖对象的虚拟成员时,继承本身在框架中实际上很有用:

          static class A : object
          {
              public static new string ToString()
              {
                  return "I am object A";
              }
      
              public static new int GetHashCode()
              {
                  return ToString().GetHashCode();
              }
          }
      

      【讨论】:

        【解决方案5】:

        静态类不能是其他类的基类,也不能扩展。

        静态类只能从“对象”类(.net 基类)继承。

        附加信息:.net 中的所有类都继承自“object”类,甚至任何静态类也是如此。

        不同之处在于,即使静态类继承了“对象类”,它也只继承了“对象”类的两个静态方法。

        其他非静态类继承其他四种方法。

        【讨论】:

          【解决方案6】:

          错误消息是虚假的。它不是说“一个”对象。它谈论的是称为“对象”的内置类型,它是 .NET 中所有内容的基础。

          应该说“静态类不能指定基类型”。

          【讨论】:

          • 不,它应该说“静态类不能指定基类型。静态类总是隐式地派生自 System.Object。”请注意,您也不能从另一个静态类派生一个静态类。
          【解决方案7】:

          如果您试图阻止人们创建该类的实例,只需添加一个私有默认构造函数。

          【讨论】:

          • 我的目标是停止制作 bar 的实例,但私有构造函数的问题是我需要将 foo 中的变量和函数也更改为 static 才能访问它们。
          • 在这种情况下,您应该使用组合而不是继承; bar 包含 foo 的静态只读实例。
          【解决方案8】:

          如前所述,C# 规范说这不能完成。您也不能使用静态类实现接口。您最好的选择是从使用静态类更改为使用使用单例模式的类。您将只有一个实例(类似于静态类的工作方式),您将能够继承行为或实现接口。

          您阅读了单身人士hereherehere

          【讨论】:

            【解决方案9】:

            我认为 C# 不支持静态类的继承。

            一种选择是使用单例模式

            public class foo
            { }
            
            public class bar : foo
            {
                private bar instance;
                public bar GetInstance()
                {
                    if(instance == null) instance = new bar();
                    return instance;
                }
            
                private bar(){} //make default constructor private to prevent instantiation 
            }
            

            【讨论】:

            • 单身不是我推荐的。使用它时要非常小心。见:google.com/…
            • 我认为你的例子有缺陷,如果两个线程成功通过 if(instance == null) 它将实例化一个新栏两次。
            • 以上代码产生错误:静态类不能有实例构造函数
            • 编辑删除栏类的静态声明。我没有说它是线程安全的,大概你可以锁定检查/创建实例。就我个人而言,我认为单身人士正在走 goto 的道路,人们认为他们总是邪恶的,但情况并非总是如此。 DI 也可能是矫枉过正
            • 考虑到它甚至不再有任何静态类,你的答案与 OP 试图做的有点远。另请注意,如果 OP 能够从类派生静态类,那么在 munificent 的解决方案中存在的任何线程问题也将存在。
            【解决方案10】:

            取自http://msdn.microsoft.com/en-us/library/79b3xss3(VS.80).aspx

            静态类的主要特点 是:

            它们只包含静态成员。

            它们不能被实例化。

            它们是密封的。

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

            因此,通过将非静态成员引入静态类,从非静态类继承违反了此列表中静态类的第一个特性。

            【讨论】:

            • 这是解决根本问题的答案。
            • 很遗憾,他们不允许您真正从静态类继承,因为我刚刚遇到了一个很方便的场景。如果要实现的话,只需要提供一个静态无参构造函数来调用基类的构造函数,所有的实例成员都会变成静态成员...
            【解决方案11】:

            来自 C# 3.0 规范,第 10.1.1.3 节:

            静态类不能包含 class-base 规范 (§10.1.4) 和 无法显式指定基类 或已实现接口的列表。一种 静态类隐式继承自 输入object

            换句话说,你不能这样做。

            【讨论】:

              【解决方案12】:

              错误信息具有误导性。

              bar 不能从 foo 继承,因为 foo 可以被实例化而 bar 不能。

              【讨论】:

              • 这本身并不是一个原因。 C# 规范很容易允许这种情况 - 只是碰巧不允许。
              • 天哪,这是乔恩·斯基特!! 感觉很幸福或什么 ;-)
              【解决方案13】:

              所有类都隐式派生自 Object。也就是说,尽管静态类(根据定义只是静态成员的容器)从对象“派生”,但您无法从这个事实中得到任何信息。

              【讨论】:

                【解决方案14】:

                不能。您必须创建一个普通类才能从其他类派生。

                【讨论】:

                  【解决方案15】:

                  不是所有的类(包括静态的)都派生自对象吗?就像默认情况下一样?

                  另外,就像它说的,“静态类不能从类型派生。”,所以我不认为你在做什么是可能的。为什么还要从一个类型派生一个静态类?

                  【讨论】:

                    猜你喜欢
                    • 2011-09-23
                    • 2010-09-22
                    • 2010-10-05
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-05-24
                    • 2011-08-09
                    • 2010-10-10
                    相关资源
                    最近更新 更多