2009-05-05 147 views
36

我最近遇到了一个问题,它似乎我需要'静态抽象'方法。我知道为什么这是不可能的,但我该如何解决这个限制?C#,实现'静态抽象'像方法

例如,我有一个抽象类,它有一个描述字符串。由于这个字串是通用于所有的情况下,它被标记为静态的,但我想需要从这个类派生的所有类提供自己的描述属性,因此我将其标记为抽象:

abstract class AbstractBase 
{ 
    ... 
    public static abstract string Description{get;} 
    ... 
} 

它不会当然编译。我想过使用接口,但接口可能不包含静态方法签名。

我应该让它变得非静态,并且总是得到一个实例来获取该类的特定信息吗?

任何想法?

+0

与此问题类似http://stackoverflow.com/questions/763344/c-virtual-or-abstract-static-methods/763364#763364 – 2009-05-05 07:07:14

+0

可能的重复[为什么我不能在C#中使用抽象静态方法? ?](https://stackoverflow.com/questions/3284/why-cant-i-have-abstract-static-methods-in-c) – 2018-01-10 04:57:47

+0

[如何实现虚拟静态属性?](https:/ /stackoverflow.com/questions/15346631/how-to-implement-virtual-static-properties) – peterh 2018-01-10 11:13:37

回答

5

结合静态和抽象是没有意义的,是的。静态背后的想法是不需要为了使用有问题的成员而提供类的实例;然而,对于抽象,我们期望一个实例是一个派生类,它提供了一个具体的实现。

我可以看到为什么你想要这种组合,但事实是唯一的效果是拒绝'this'或任何非静态成员的实现使用。也就是说,即使调用抽象或'静态抽象'成员之间没有根本的区别(因为两者都需要一个具体的实例来找出使用什么实现),父类将决定对派生类的实现进行限制,

31

你不能。

要做到这一点的地方是属性。

[Name("FooClass")] 
class Foo 
{ 
} 
3

它不是静态的,如果它有一个实例被调用。

如果你不是在实例上调用它,那么在播放时就没有多态性(即就语言而言,ChildA.Description与ChildB.Description完全无关)。

5

如果它是静态的,只有一个变量的实例,我不明白如果我们可以在派生类中使用静态变量来完成你想完成的工作,那么继承是有意义的。就我个人而言,我认为你要尽量避免实例变种。

为什么不只是经典的方式?

abstract class AbstractBase 
{ 
    protected string _Description = "I am boring abstract default value"; 
} 

class Foo : AbstractBase { 

    public Foo() { 
     _Description = "I am foo!"; 
    } 
} 
5

如果你不介意推迟到实现明智地实施Description属性,你可以简单地做

public abstract string ClassDescription {get; } 
// ClassDescription is more intention-revealing than Description 

而且实现类会做这样的事情:

static string classDescription="My Description for this class"; 
override string ClassDescription { get { return classDescription; } } 

然后,你的班级必须遵守描述的合同,但你要让他们明智地做到这一点。没有办法以面向对象的方式指定实现(除非通过残酷,脆弱的黑客)。

但是,在我看来,这个描述是类元数据,所以我更愿意使用其他人描述的属性机制。如果您特别担心多次使用反射,请创建一个反映您所关注属性的对象,并在“类型”和“描述”之间存储字典。这将最大限度地减少反射(除了运行时类型检测,这并不是那么糟糕)。字典可以存储为通常需要此信息的任何类的成员,或者,如果域中的客户端需要它,可以通过单例或上下文对象进行存储。

0

您可以使“抽象”基本方法抛出Exception,因此如果开发人员试图在不重写的情况下在子类上调用此方法,则会“警告”开发人员。

缺点是可能会扩展类而不使用此方法。然后参考提供的其他答案。