如何通过使用接口或抽象来确保类具有静态属性?
我有一个抽象类 - 比方说 myBase。我希望从 myBase 派生的所有类都有一个名为的静态字段,
public static List<string> MyPArameterNames
{
get {return _myParameterNames;}
}
因此,每个子类都可以知道它使用的参数名称;我想要静态,因为我不想为此创建一个实例。
我怎样才能实现这个目标?
I have one abstract class -let's say myBase. And I want all the classes derived from myBase to have one static field called
public static List<string> MyPArameterNames
{
get {return _myParameterNames;}
}
So, every child class can tell what parameter names it uses; I want static because I do not want to create an instance just for this.
How can I achieve this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
你不能那样做。接口、抽象等不能应用于静态成员。如果您想完成此任务,则必须手动记住在所有派生类上执行此操作。
此外,静态成员由派生类继承。如果子类希望指定替代行为,则必须隐藏静态父成员。
You can't do that. Interfaces, abstract, etc. cannot apply to static members. If you want to accomplish this, you will have to manually remember to do it on all deriving classes.
Also, static members are inherited by deriving classes. Child classes must hide the static parent member if they wish to specify alternate behavior.
从 C# 11 开始,您可以按照您的预期进行操作:
请注意,如果您想强制派生类来实现属性,则必须声明属性
abstract
。如果您没有将其定义为abstract
,则必须提供默认实现。在这种情况下,派生类可以忽略该属性,因为默认实现将始终存在。As of C# 11 you can do it as you would probably expect:
Note that you must declare your property
abstract
if you want to enforce deriving classes to implement it. If you don't define it asabstract
, you must provide a default implementation. In this case, derived classes can ignore the property as the default implementation will always be there.无论如何,这没有意义,因为如果不确定类型,您就无法访问该静态属性,从而破坏了接口的全部意义。
我只是在接口上放置一个属性,并将其路由到静态成员。
但这引出了第二个问题——你想要实现什么目标?为什么类中需要有一个静态成员?您真正想要的是,给定一个对象,能够确定它具有哪些属性,对吧?那么,为什么您的代码会关心它们是静态存储还是按实例存储呢?
看来您将合同(您希望能够做什么)与实施(服务提供商如何实现目标)混淆了。
It doesn't make sense, anyway, as you'd have no way to access that static property without determining the type, thus breaking the whole point of having an interface anyway.
I'd just put a property on the interface, and route it to the static member.
But that leads me to the second question - what is it that you are trying to accomplish? Why do you need to have a static member on the class? What you really want is, given an object, to be able to determine what properties it has, right? So why would your code care if they're stored statically or per instance?
It seems like you're confusing contract (what you want to be able to do) with implementation (how the provider of the service accomplishes the goal).
好的。也许是我表达得不够清楚。但我通过执行以下操作基本上已经实现了我所需要的:
因此,如果尝试 MyParameterNames 属性访问该派生类的参数名称,则从此类派生的任何类都会抛出异常。
这不是一个完美的方法,但它在某种程度上帮助我克服了我的问题。
Ok. Maybe I was not clear enough. But I have achieved basically what I need by doing something like this:
So any class derived from this class, will throw an exception if MyParameterNames property is tried to reach the parameter names of that derivedclass.
Not a perfect way, but it helps me to overcome my problem in a way.
解决方案的所有部分都在这里,分布在多个答案中。
虽然它仍然不允许您从 AbstractClass.MyParameterNames 访问 Subclass.MyParameterNames,但您将能够确保 AbastractClass 的所有实现都具有可用的属性。
但是,根据用例的具体情况,最好将 MyParameterNames 公开为非静态成员,并简单地将其实现为单例,以便每个子类只有一份列表副本。无论哪种方式,您仍然需要初始化该类的实例才能获取所需的数据。
至少,要获取静态数据,您需要知道您正在处理的特定子类,因此尝试从接口查看它没有多大意义,它可以是任意的、未知的数据类型。
All the pieces of the solution are here, spread across multiple answers.
While it still will not allow you to access Subclass.MyParameterNames from AbstractClass.MyParameterNames, you will be able to ensure that all implementations of AbastractClass have that property available.
Depending on the specifics of your use case, however, it may be better to expose MyParameterNames it as a non-static member, and simply implement it as a singleton so that there is only one copy of the list for each subclass. Either way, you'll still need to initialize an instance of the class in order to get the data you want.
At the very least, to get the static data, you'll need to know what specific subclass you're dealing with, so it doesn't make much sense to attempt to look at it from an interface, which can be an arbitrary, unknown data type.
这是不可能的。继承不能应用于类型的成员(静态成员)。
It is imposible. Inheritance cannot be aplied to the members of the type (static members).
虽然接口上不可能有静态值,但抽象类上可以有静态值。不过,这个实例是在抽象类的级别上保存的;所以对于所有派生类来说都是通用的。根据您的需要,您可以利用它来发挥自己的优势;即在您的基类上有一个字典,其键是一个类型(该类型是派生类的类型),然后将您的列表保存在该字典下。
它与静态属性并不完全相同(例如,您不能在不先创建实例的情况下简单地访问该属性),但它可能适用于某些用例。
Whilst it's not possible to have a
static
value on an interface, it is possible to have a static value on an abstract class. This instance is held at the abstract class's level though; so will be common to all derived classes. Depending on your needs you can use this to your advantage; i.e. have a dictionary on your base class the key for which is a type (the type being that of the derived class), then hold your lists under that.It's not exactly the same as having a static property (e.g. you cannot simply access the property without first creating an instance), but it may work well for some use cases.
您可以在
MyBase
的构造函数中调用GetType()
并使用反射来确保派生类具有正确的属性。显然,这只会在运行时获取它,但我不太确定这个约束的意义是什么:如果静态属性不存在会有什么危害?You can, in the constructor for
MyBase
, callGetType()
and use reflection to ensure the derived class has the correct property. Obviously, that's only going to pick it up at runtime, but I'm not really sure what the point of this constraint would be anyway: what's the harm if the static property isn't there?为什么不使 MyParameterNames Virtual 并在派生类中重写它们以引发异常
Why not make the make MyParameterNames Virtual and override them in the derived classes to throw the exception