为什么我不能声明C#方法虚拟和静态?

时间:2022-09-02 12:02:12

I have a helper class that is just a bunch of static methods and would like to subclass the helper class. Some behavior is unique depending on the subclass so I would like to call a virtual method from the base class, but since all the methods are static I can't create a plain virtual method (need object reference in order to access virtual method).

我有一个辅助类,它只是一堆静态方法,并且想要辅助类的子类。某些行为是独特的,具体取决于子类,所以我想从基类调用虚方法,但由于所有方法都是静态的,我无法创建普通的虚方法(需要对象引用才能访问虚方法)。

Is there any way around this? I guess I could use a singleton.. HelperClass.Instance.HelperMethod() isn't so much worse than HelperClass.HelperMethod(). Brownie points for anyone that can point out some languages that support virtual static methods.

有没有办法解决?我想我可以使用单例.. HelperClass.Instance.HelperMethod()并不比HelperClass.HelperMethod()差。布朗尼指出任何可以指出支持虚拟静态方法的语言的人。

Edit: OK yeah I'm crazy. Google search results had me thinking I wasn't for a bit there.

编辑:好的,我疯了。谷歌搜索结果让我觉得我不是那里的。

14 个解决方案

#1


43  

Virtual static methods don't make sense. If I call HelperClass.HelperMethod();, why would I expect some random subclass' method to be called? The solution really breaks down when you have 2 subclasses of HelperClass - which one would you use?

虚拟静态方法没有意义。如果我调用HelperClass.HelperMethod();,为什么我会期望调用一些随机子类'方法?当你有2个HelperClass子类时,解决方案真的会崩溃 - 你会使用哪一个?

If you want to have overrideable static-type methods you should probably go with:

如果你想拥有可重写的静态类型方法,你可能应该使用:

  • A singleton, if you want the same subclass to be used globally.
  • 单例,如果您希望全局使用相同的子类。

  • A tradition class hierarchy, with a factory or dependency injection, if you want different behavior in different parts of your application.
  • 传统类层次结构,具有工厂或依赖注入,如果您希望在应用程序的不同部分中使用不同的行为。

Choose whichever solution makes more sense in your situation.

选择在您的情况下更有意义的解决方案。

#2


29  

I don't think you are crazy. You just want to use what is impossible currently in .NET.

Your request for virtual static method would have so much sense if we are talking about generics. For example my future request for CLR designers is to allow me to write intereface like this:

我不认为你疯了。您只想使用.NET当前不可能的东西。如果我们谈论泛型,你对虚拟静态方法的请求会有很大的意义。例如,我对CLR设计师的未来要求是允许我写这样的界面:

public interface ISumable<T>
{
  static T Add(T left, T right);
}

and use it like this:

并像这样使用它:

public T Aggregate<T>(T left, T right) where T : ISumable<T>
{
  return T.Add(left, right);
}

But it's impossible right now, so I'm doing it like this:

但现在不可能,所以我这样做:

    public static class Static<T> where T : new()
    {
      public static T Value = new T();
    }

    public interface ISumable<T>
    {
      T Add(T left, T right);
    }

    public T Aggregate<T>(T left, T right) where T : ISumable<T>, new()
    {
      return Static<T>.Value.Add(left, right);
    }

#3


13  

Indeed, this can be done in Delphi. An example:

实际上,这可以在Delphi中完成。一个例子:

type
  TForm1 = class(TForm)
    procedure FormShow(Sender: TObject);
  end;

  TTestClass = class
  public
    class procedure TestMethod(); virtual;
  end;

  TTestDerivedClass = class(TTestClass)
  public
    class procedure TestMethod(); override;
  end;

  TTestMetaClass = class of TTestClass;

var
  Form1: TForm1;

implementation

{$R *.dfm}

class procedure TTestClass.TestMethod();
begin
  Application.MessageBox('base', 'Message');
end;

class procedure TTestDerivedClass.TestMethod();
begin
  Application.MessageBox('descendant', 'Message');
end;


procedure TForm1.FormShow(Sender: TObject);
var
  sample: TTestMetaClass;
begin
  sample := TTestClass;
  sample.TestMethod;
  sample := TTestDerivedClass;
  sample.TestMethod;
end;

Quite interesting. I no longer use Delphi, but I recall being able to very easily create different types of controls on a custom designer canvas using the metaclass feature: the control class, eg. TButton, TTextBox etc. was a parameter, and I could call the appropriate constructor using the actual metaclass argument.

很有趣。我不再使用Delphi,但我记得能够使用元类功能在自定义设计器画布上轻松创建不同类型的控件:控件类,例如。 TButton,TTextBox等是一个参数,我可以使用实际的元类参数调用适当的构造函数。

Kind of the poor man's factory pattern :)

那种穷人的工厂模式:)

#4


11  

You can achieve the same effect by just having a regular static method and then shadow it with the new keyword

只需使用常规静态方法然后使用new关键字对其进行遮蔽即可达到相同的效果

public class Base 
{
    //Other stuff

    public static void DoSomething()
    {
        Console.WriteLine("Base");
    }
}

public class SomeClass : Base
{
    public new static void DoSomething()
    {
        Console.WriteLine("SomeClass");
    }
}
public class SomeOtherClass : Base
{
}

Then you can call the methods like so

然后你可以调用这样的方法

Base.DoSomething(); //Base
SomeClass.DoSomething(); //SomeClass
SomeOtherClass.DoSomething(); //Base

#5


8  

I come from Delphi and this is a feature among many that I sorely miss in c#. Delphi would allow you to create typed type references and you could pass the type of a derived class wherever the type of a parent class was needed. This treatment of types as objects had powerful utility. In particular allowing run time determination of meta data. I am horribly mixing syntax here but in c# it would look something like:

我来自Delphi,这是我在c#中非常想念的很多功能。 Delphi允许您创建类型化类型引用,并且您可以在需要父类类型的任何地方传递派生类的类型。这种对象类型的处理具有强大的实用性。特别是允许运行时确定元数据。我在这里混合语法非常可怕,但在c#中它看起来像:

    class Root {
       public static virtual string TestMethod() {return "Root"; }
    }
    TRootClass = class of TRoot; // Here is the typed type declaration

    class Derived : Root {
       public static overide string TestMethod(){ return "derived"; }
    }

   class Test {
        public static string Run(){
           TRootClass rc;
           rc = Root;
           Test(rc);
           rc = Derived();
           Test(rc);
        }
        public static Test(TRootClass AClass){
           string str = AClass.TestMethod();
           Console.WriteLine(str);
        }
    } 

would produce: Root derived

会产生:根源

#6


7  

a static method exists outside of an instance of a class. It cannot use any non-static data.

静态方法存在于类的实例之外。它不能使用任何非静态数据。

a virtual method will be "overwritten" by an overloaded function depending of the type of an instance.

虚拟方法将被重载函数“覆盖”,具体取决于实例的类型。

so you have a clear contradiction between static and virtual.

所以你在静态和虚拟之间有明显的矛盾。

This is not a problem of support, It is a concept.

这不是支持问题,而是一个概念。

Update: I was proven wrong here(see comments):

更新:我在这里被证明是错的(见评论):

So I doubt you will find any OOP-Language which will support virtual static methods.

所以我怀疑你会找到任何支持虚拟静态方法的OOP语言。

#7


6  

You are not crazy. What you are referring to is called Late Static Binding; it's been recently added to PHP. There's a great thread that describes it - here: When would you need to use late static binding?

你并不疯狂。你所指的是称为Late Static Binding;它最近被添加到PHP。有一个伟大的线程描述它 - 这里:你什么时候需要使用后期静态绑定?

#8


2  

Mart got it right with the 'new' keyword. I actually got here because I needed this type of functionality and Mart's solution works fine. In fact I took it one better and made my base class method abstract to force the programmer to supply this field.

Mart用'new'关键字做对了。我实际上到这里是因为我需要这种功能,Mart的解决方案运行正常。事实上,我把它更好,并使我的基类方法抽象,以迫使程序员提供这个字段。

My scenario was as follows:

我的方案如下:

I have a base class HouseDeed. Each House type is derived from HouseDeed must have a price.

我有一个基类HouseDeed。每个House类型都源自HouseDeed必须有价格。

Here is the partial base HouseDeed class:

这是部分基础HouseDeed类:

public abstract class HouseDeed : Item
{
    public static int m_price = 0;
    public abstract int Price { get; }
    /* more impl here */
}

Now lets look at two derived house types:

现在让我们看看两个派生的房屋类型:

public class FieldStoneHouseDeed : HouseDeed
{
    public static new int m_price = 43800;
    public override int Price { get { return m_price; } }
    /* more impl here */
}

and...

public class SmallTowerDeed : HouseDeed
{
    public static new int m_price = 88500;
    public override int Price { get { return m_price; } }
    /* more impl here */
}

As you can see I can access the price of the house via type SmallTowerDeed.m_price, and the instance new SmallTowerDeed().Price And being abstract, this mechanism nags the programmer into supplying a price for each new derived house type.

正如你所看到的,我可以通过类型SmallTowerDeed.m_price和实例新的SmallTowerDeed()访问房子的价格。价格和抽象,这个机制让程序员唠叨为每个新派生的房屋类型提供价格。

Someone pointed how 'static virtual' and 'virtual' are conceptually at odds with one another. I disagree. In this example, the static methods do not need access to the instance data, and so the requirements that (1) the price be available via the TYPE alone, and that (2) a price be supplied are met.

有人指出“静态虚拟”和“虚拟”在概念上是如何相互矛盾的。我不同意。在此示例中,静态方法不需要访问实例数据,因此满足以下要求:(1)仅通过TYPE可获得价格,以及(2)提供价格。

#9


1  

I heard that Delphi suports something like this. It seems it does it by making classes object instances of a metaclass.

我听说Delphi支持这样的东西。它似乎通过使类对象的元类实例来实现。

I've not seen it work, so I'm not sure that it works, or what's the point for that.

我没有看到它的工作,所以我不确定它是否有效,或者它的重点是什么。

P.S. Please correct me if I'm wrong, since it's not my domain.

附:如果我错了,请纠正我,因为这不是我的域名。

#10


1  

Because a virtual method uses the defined type of the instantiated object to determine which implementation to execute, (as opposed to the declared type of the reference variable)

因为虚方法使用实例化对象的已定义类型来确定要执行的实现,(与引用变量的声明类型相反)

... and static, of course, is all about not caring if there's even an instantiated instance of the class at all...

...当然,如果甚至有一个实例化的类实例,那么静态就是不关心......

So these are incompatible.

所以这些是不相容的。

Bottom line, is if you want to change behavior based on which subclass an instance is, then the methods should have been virtual methods on the base class, not static methods.

最重要的是,如果您想根据实例所在的子类更改行为,那么这些方法应该是基类的虚方法,而不是静态方法。

But, as you already have these static methods, and now need to override them, you can solve your problem by this: Add virtual instance methods to the base class that simply delegate to the static methods, and then override those virtual instance wrapper methods (not the static ones) in each derived subclass, as appropriate...

但是,由于您已经拥有这些静态方法,现在需要覆盖它们,您可以通过以下方法解决您的问题:将虚拟实例方法添加到简单地委托给静态方法的基类,然后覆盖这些虚拟实例包装器方法(在每个派生的子类中,不是静态的),视情况而定......

#11


1  

It is actually possible to combine virtual and static for a method or a member by using the keyword new instead of virtual.

实际上,可以使用关键字new而不是virtual来组合方法或成员的虚拟和静态。

Here is an example:

这是一个例子:

class Car
{
    public static int TyreCount = 4;
    public virtual int GetTyreCount() { return TyreCount; }
}
class Tricar : Car
{
    public static new int TyreCount = 3;
    public override int GetTyreCount() { return TyreCount; }
}

...

Car[] cc = new Car[] { new Tricar(), new Car() };
int t0 = cc[0].GetTyreCount(); // t0 == 3
int t1 = cc[1].GetTyreCount(); // t1 == 4

Obviously the TyreCount value could have been set in the overridden GetTyreCount method, but this avoids duplicating the value. It is possible to get the value both from the class and the class instance.

显然,TyreCount值可以在重写的GetTyreCount方法中设置,但这可以避免重复该值。可以从类和类实例中获取值。

Now can someone find a really intelligent usage of that feature?

现在有人可以找到该功能的真正智能用途吗?

#12


1  

An override method provides a new implementation of a member that is inherited from a base class. The method that is overridden by an override declaration is known as the overridden base method. The overridden base method must have the same signature as the override method. You cannot override a non-virtual or static method. The overridden base method must be virtual, abstract, or override.

override方法提供从基类继承的成员的新实现。由覆盖声明覆盖的方法称为重写的基本方法。重写的基本方法必须与覆盖方法具有相同的签名。您不能覆盖非虚拟或静态方法。重写的基本方法必须是虚拟,抽象或覆盖。

An override declaration cannot change the accessibility of the virtual method. Both the override method and the virtual method must have the same access level modifier.

覆盖声明不能更改虚拟方法的可访问性。覆盖方法和虚方法都必须具有相同的访问级别修饰符。

You cannot use the new, static, or virtual modifiers to modify an override method.

您不能使用new,static或virtual修饰符来修改覆盖方法。

An overriding property declaration must specify exactly the same access modifier, type, and name as the inherited property, and the overridden property must be virtual, abstract, or override.

覆盖属性声明必须指定与继承属性完全相同的访问修饰符,类型和名称,并且重写的属性必须是虚拟,抽象或覆盖。

#13


1  

There is a way to force an inheritance of "abstract static" methods from an abstract generic class. See as follow :

有一种方法可以从抽象泛型类强制继承“抽象静态”方法。见如下:

public abstract class Mother<T> where T : Mother<T>, new()
{
    public abstract void DoSomething();

    public static void Do()
    {
        (new T()).DoSomething();
    }

}

public class ChildA : Mother<ChildA>
{
    public override void DoSomething() { /* Your Code */ }
}

public class ChildB : Mother<ChildB>
{
    public override void DoSomething() { /* Your Code */ }
}

Example (using the previous Mother):

示例(使用以前的母亲):

public class ChildA : Mother<ChildA>
{
    public override void DoSomething() { Console.WriteLine("42"); }
}

public class ChildB : Mother<ChildB>
{
    public override void DoSomething() { Console.WriteLine("12"); }
}

public class Program
{
    static void Main()
    {
        ChildA.Do();  //42
        ChildB.Do();  //12
        Console.ReadKey();
    }
}

It's not that great since you can inherit from only one abstract class and it will ask you to be lenient with your new() implementation.

它不是那么好,因为你只能从一个抽象类继承,它会要求你对你的new()实现宽容。

More, I think it will be costly memory-wise depending on the size of your inherited classes. In case you have memory issue, you would have to set every properties/variables after your new in a public method which is an awful way to have default values.

更多,我认为根据你继承的类的大小,它将是昂贵的内存。如果您遇到内存问题,则必须在新方法之后在公共方法中设置每个属性/变量,这是一种非常有效的默认值。

#14


0  

You can use the new keyword

您可以使用new关键字

namespace AspDotNetStorefront
{
    // This Class is need to override StudioOnlineCommonHelper Methods in a branch
    public class StudioOnlineCommonHelper : StudioOnlineCore.StudioOnlineCommonHelper
    {
        //
        public static new void DoBusinessRulesChecks(Page page)
        {
            StudioOnlineCore.StudioOnlineCommonHelper.DoBusinessRulesChecks(page);
        }
    }
}

#1


43  

Virtual static methods don't make sense. If I call HelperClass.HelperMethod();, why would I expect some random subclass' method to be called? The solution really breaks down when you have 2 subclasses of HelperClass - which one would you use?

虚拟静态方法没有意义。如果我调用HelperClass.HelperMethod();,为什么我会期望调用一些随机子类'方法?当你有2个HelperClass子类时,解决方案真的会崩溃 - 你会使用哪一个?

If you want to have overrideable static-type methods you should probably go with:

如果你想拥有可重写的静态类型方法,你可能应该使用:

  • A singleton, if you want the same subclass to be used globally.
  • 单例,如果您希望全局使用相同的子类。

  • A tradition class hierarchy, with a factory or dependency injection, if you want different behavior in different parts of your application.
  • 传统类层次结构,具有工厂或依赖注入,如果您希望在应用程序的不同部分中使用不同的行为。

Choose whichever solution makes more sense in your situation.

选择在您的情况下更有意义的解决方案。

#2


29  

I don't think you are crazy. You just want to use what is impossible currently in .NET.

Your request for virtual static method would have so much sense if we are talking about generics. For example my future request for CLR designers is to allow me to write intereface like this:

我不认为你疯了。您只想使用.NET当前不可能的东西。如果我们谈论泛型,你对虚拟静态方法的请求会有很大的意义。例如,我对CLR设计师的未来要求是允许我写这样的界面:

public interface ISumable<T>
{
  static T Add(T left, T right);
}

and use it like this:

并像这样使用它:

public T Aggregate<T>(T left, T right) where T : ISumable<T>
{
  return T.Add(left, right);
}

But it's impossible right now, so I'm doing it like this:

但现在不可能,所以我这样做:

    public static class Static<T> where T : new()
    {
      public static T Value = new T();
    }

    public interface ISumable<T>
    {
      T Add(T left, T right);
    }

    public T Aggregate<T>(T left, T right) where T : ISumable<T>, new()
    {
      return Static<T>.Value.Add(left, right);
    }

#3


13  

Indeed, this can be done in Delphi. An example:

实际上,这可以在Delphi中完成。一个例子:

type
  TForm1 = class(TForm)
    procedure FormShow(Sender: TObject);
  end;

  TTestClass = class
  public
    class procedure TestMethod(); virtual;
  end;

  TTestDerivedClass = class(TTestClass)
  public
    class procedure TestMethod(); override;
  end;

  TTestMetaClass = class of TTestClass;

var
  Form1: TForm1;

implementation

{$R *.dfm}

class procedure TTestClass.TestMethod();
begin
  Application.MessageBox('base', 'Message');
end;

class procedure TTestDerivedClass.TestMethod();
begin
  Application.MessageBox('descendant', 'Message');
end;


procedure TForm1.FormShow(Sender: TObject);
var
  sample: TTestMetaClass;
begin
  sample := TTestClass;
  sample.TestMethod;
  sample := TTestDerivedClass;
  sample.TestMethod;
end;

Quite interesting. I no longer use Delphi, but I recall being able to very easily create different types of controls on a custom designer canvas using the metaclass feature: the control class, eg. TButton, TTextBox etc. was a parameter, and I could call the appropriate constructor using the actual metaclass argument.

很有趣。我不再使用Delphi,但我记得能够使用元类功能在自定义设计器画布上轻松创建不同类型的控件:控件类,例如。 TButton,TTextBox等是一个参数,我可以使用实际的元类参数调用适当的构造函数。

Kind of the poor man's factory pattern :)

那种穷人的工厂模式:)

#4


11  

You can achieve the same effect by just having a regular static method and then shadow it with the new keyword

只需使用常规静态方法然后使用new关键字对其进行遮蔽即可达到相同的效果

public class Base 
{
    //Other stuff

    public static void DoSomething()
    {
        Console.WriteLine("Base");
    }
}

public class SomeClass : Base
{
    public new static void DoSomething()
    {
        Console.WriteLine("SomeClass");
    }
}
public class SomeOtherClass : Base
{
}

Then you can call the methods like so

然后你可以调用这样的方法

Base.DoSomething(); //Base
SomeClass.DoSomething(); //SomeClass
SomeOtherClass.DoSomething(); //Base

#5


8  

I come from Delphi and this is a feature among many that I sorely miss in c#. Delphi would allow you to create typed type references and you could pass the type of a derived class wherever the type of a parent class was needed. This treatment of types as objects had powerful utility. In particular allowing run time determination of meta data. I am horribly mixing syntax here but in c# it would look something like:

我来自Delphi,这是我在c#中非常想念的很多功能。 Delphi允许您创建类型化类型引用,并且您可以在需要父类类型的任何地方传递派生类的类型。这种对象类型的处理具有强大的实用性。特别是允许运行时确定元数据。我在这里混合语法非常可怕,但在c#中它看起来像:

    class Root {
       public static virtual string TestMethod() {return "Root"; }
    }
    TRootClass = class of TRoot; // Here is the typed type declaration

    class Derived : Root {
       public static overide string TestMethod(){ return "derived"; }
    }

   class Test {
        public static string Run(){
           TRootClass rc;
           rc = Root;
           Test(rc);
           rc = Derived();
           Test(rc);
        }
        public static Test(TRootClass AClass){
           string str = AClass.TestMethod();
           Console.WriteLine(str);
        }
    } 

would produce: Root derived

会产生:根源

#6


7  

a static method exists outside of an instance of a class. It cannot use any non-static data.

静态方法存在于类的实例之外。它不能使用任何非静态数据。

a virtual method will be "overwritten" by an overloaded function depending of the type of an instance.

虚拟方法将被重载函数“覆盖”,具体取决于实例的类型。

so you have a clear contradiction between static and virtual.

所以你在静态和虚拟之间有明显的矛盾。

This is not a problem of support, It is a concept.

这不是支持问题,而是一个概念。

Update: I was proven wrong here(see comments):

更新:我在这里被证明是错的(见评论):

So I doubt you will find any OOP-Language which will support virtual static methods.

所以我怀疑你会找到任何支持虚拟静态方法的OOP语言。

#7


6  

You are not crazy. What you are referring to is called Late Static Binding; it's been recently added to PHP. There's a great thread that describes it - here: When would you need to use late static binding?

你并不疯狂。你所指的是称为Late Static Binding;它最近被添加到PHP。有一个伟大的线程描述它 - 这里:你什么时候需要使用后期静态绑定?

#8


2  

Mart got it right with the 'new' keyword. I actually got here because I needed this type of functionality and Mart's solution works fine. In fact I took it one better and made my base class method abstract to force the programmer to supply this field.

Mart用'new'关键字做对了。我实际上到这里是因为我需要这种功能,Mart的解决方案运行正常。事实上,我把它更好,并使我的基类方法抽象,以迫使程序员提供这个字段。

My scenario was as follows:

我的方案如下:

I have a base class HouseDeed. Each House type is derived from HouseDeed must have a price.

我有一个基类HouseDeed。每个House类型都源自HouseDeed必须有价格。

Here is the partial base HouseDeed class:

这是部分基础HouseDeed类:

public abstract class HouseDeed : Item
{
    public static int m_price = 0;
    public abstract int Price { get; }
    /* more impl here */
}

Now lets look at two derived house types:

现在让我们看看两个派生的房屋类型:

public class FieldStoneHouseDeed : HouseDeed
{
    public static new int m_price = 43800;
    public override int Price { get { return m_price; } }
    /* more impl here */
}

and...

public class SmallTowerDeed : HouseDeed
{
    public static new int m_price = 88500;
    public override int Price { get { return m_price; } }
    /* more impl here */
}

As you can see I can access the price of the house via type SmallTowerDeed.m_price, and the instance new SmallTowerDeed().Price And being abstract, this mechanism nags the programmer into supplying a price for each new derived house type.

正如你所看到的,我可以通过类型SmallTowerDeed.m_price和实例新的SmallTowerDeed()访问房子的价格。价格和抽象,这个机制让程序员唠叨为每个新派生的房屋类型提供价格。

Someone pointed how 'static virtual' and 'virtual' are conceptually at odds with one another. I disagree. In this example, the static methods do not need access to the instance data, and so the requirements that (1) the price be available via the TYPE alone, and that (2) a price be supplied are met.

有人指出“静态虚拟”和“虚拟”在概念上是如何相互矛盾的。我不同意。在此示例中,静态方法不需要访问实例数据,因此满足以下要求:(1)仅通过TYPE可获得价格,以及(2)提供价格。

#9


1  

I heard that Delphi suports something like this. It seems it does it by making classes object instances of a metaclass.

我听说Delphi支持这样的东西。它似乎通过使类对象的元类实例来实现。

I've not seen it work, so I'm not sure that it works, or what's the point for that.

我没有看到它的工作,所以我不确定它是否有效,或者它的重点是什么。

P.S. Please correct me if I'm wrong, since it's not my domain.

附:如果我错了,请纠正我,因为这不是我的域名。

#10


1  

Because a virtual method uses the defined type of the instantiated object to determine which implementation to execute, (as opposed to the declared type of the reference variable)

因为虚方法使用实例化对象的已定义类型来确定要执行的实现,(与引用变量的声明类型相反)

... and static, of course, is all about not caring if there's even an instantiated instance of the class at all...

...当然,如果甚至有一个实例化的类实例,那么静态就是不关心......

So these are incompatible.

所以这些是不相容的。

Bottom line, is if you want to change behavior based on which subclass an instance is, then the methods should have been virtual methods on the base class, not static methods.

最重要的是,如果您想根据实例所在的子类更改行为,那么这些方法应该是基类的虚方法,而不是静态方法。

But, as you already have these static methods, and now need to override them, you can solve your problem by this: Add virtual instance methods to the base class that simply delegate to the static methods, and then override those virtual instance wrapper methods (not the static ones) in each derived subclass, as appropriate...

但是,由于您已经拥有这些静态方法,现在需要覆盖它们,您可以通过以下方法解决您的问题:将虚拟实例方法添加到简单地委托给静态方法的基类,然后覆盖这些虚拟实例包装器方法(在每个派生的子类中,不是静态的),视情况而定......

#11


1  

It is actually possible to combine virtual and static for a method or a member by using the keyword new instead of virtual.

实际上,可以使用关键字new而不是virtual来组合方法或成员的虚拟和静态。

Here is an example:

这是一个例子:

class Car
{
    public static int TyreCount = 4;
    public virtual int GetTyreCount() { return TyreCount; }
}
class Tricar : Car
{
    public static new int TyreCount = 3;
    public override int GetTyreCount() { return TyreCount; }
}

...

Car[] cc = new Car[] { new Tricar(), new Car() };
int t0 = cc[0].GetTyreCount(); // t0 == 3
int t1 = cc[1].GetTyreCount(); // t1 == 4

Obviously the TyreCount value could have been set in the overridden GetTyreCount method, but this avoids duplicating the value. It is possible to get the value both from the class and the class instance.

显然,TyreCount值可以在重写的GetTyreCount方法中设置,但这可以避免重复该值。可以从类和类实例中获取值。

Now can someone find a really intelligent usage of that feature?

现在有人可以找到该功能的真正智能用途吗?

#12


1  

An override method provides a new implementation of a member that is inherited from a base class. The method that is overridden by an override declaration is known as the overridden base method. The overridden base method must have the same signature as the override method. You cannot override a non-virtual or static method. The overridden base method must be virtual, abstract, or override.

override方法提供从基类继承的成员的新实现。由覆盖声明覆盖的方法称为重写的基本方法。重写的基本方法必须与覆盖方法具有相同的签名。您不能覆盖非虚拟或静态方法。重写的基本方法必须是虚拟,抽象或覆盖。

An override declaration cannot change the accessibility of the virtual method. Both the override method and the virtual method must have the same access level modifier.

覆盖声明不能更改虚拟方法的可访问性。覆盖方法和虚方法都必须具有相同的访问级别修饰符。

You cannot use the new, static, or virtual modifiers to modify an override method.

您不能使用new,static或virtual修饰符来修改覆盖方法。

An overriding property declaration must specify exactly the same access modifier, type, and name as the inherited property, and the overridden property must be virtual, abstract, or override.

覆盖属性声明必须指定与继承属性完全相同的访问修饰符,类型和名称,并且重写的属性必须是虚拟,抽象或覆盖。

#13


1  

There is a way to force an inheritance of "abstract static" methods from an abstract generic class. See as follow :

有一种方法可以从抽象泛型类强制继承“抽象静态”方法。见如下:

public abstract class Mother<T> where T : Mother<T>, new()
{
    public abstract void DoSomething();

    public static void Do()
    {
        (new T()).DoSomething();
    }

}

public class ChildA : Mother<ChildA>
{
    public override void DoSomething() { /* Your Code */ }
}

public class ChildB : Mother<ChildB>
{
    public override void DoSomething() { /* Your Code */ }
}

Example (using the previous Mother):

示例(使用以前的母亲):

public class ChildA : Mother<ChildA>
{
    public override void DoSomething() { Console.WriteLine("42"); }
}

public class ChildB : Mother<ChildB>
{
    public override void DoSomething() { Console.WriteLine("12"); }
}

public class Program
{
    static void Main()
    {
        ChildA.Do();  //42
        ChildB.Do();  //12
        Console.ReadKey();
    }
}

It's not that great since you can inherit from only one abstract class and it will ask you to be lenient with your new() implementation.

它不是那么好,因为你只能从一个抽象类继承,它会要求你对你的new()实现宽容。

More, I think it will be costly memory-wise depending on the size of your inherited classes. In case you have memory issue, you would have to set every properties/variables after your new in a public method which is an awful way to have default values.

更多,我认为根据你继承的类的大小,它将是昂贵的内存。如果您遇到内存问题,则必须在新方法之后在公共方法中设置每个属性/变量,这是一种非常有效的默认值。

#14


0  

You can use the new keyword

您可以使用new关键字

namespace AspDotNetStorefront
{
    // This Class is need to override StudioOnlineCommonHelper Methods in a branch
    public class StudioOnlineCommonHelper : StudioOnlineCore.StudioOnlineCommonHelper
    {
        //
        public static new void DoBusinessRulesChecks(Page page)
        {
            StudioOnlineCore.StudioOnlineCommonHelper.DoBusinessRulesChecks(page);
        }
    }
}