如何强制派生类包含某些具有默认值的属性
我有一个角色扮演游戏的类结构,如下所示...
public abstract class Item
{
public abstract string Name { get; set; }
}
public abstract class Armor : Item
{
public override string Name { get; set; }
}
public class Helmet : Armor
{
public override string Name { get; set; }
}
基本上,我试图强制每个派生类型都包含“名称”属性。这是最好的方法吗?我知道我可以从 Item.Name 中删除“abstract”,然后删除 Armor 和 Helmet 中覆盖的“Name”属性。如果我这样做,代码看起来会更干净一些,但我可能会忘记在这些派生类中设置 base.Name。
有人可以帮我看看最好的方法吗?
编辑: 抱歉,让我再澄清一下我的问题。我想确定两件事。 1)Name属性存在于所有派生类中 2) Name 属性不为 null 或为空
我基本上想强制从 Item 派生的任何类(并且不是抽象的)都具有 Name 值。
I have a class structure for a role playing game which looks like this...
public abstract class Item
{
public abstract string Name { get; set; }
}
public abstract class Armor : Item
{
public override string Name { get; set; }
}
public class Helmet : Armor
{
public override string Name { get; set; }
}
Basically, I am trying to force every derived type to include a "Name" property. Is this the best way to do it? I know I can remove "abstract" from Item.Name and then remove the overriden "Name" properties in Armor and Helmet. If I do that the code looks a little cleaner but I might forget to set the base.Name in these derived classes.
Could someone help show me the best way to do this?
EDIT:
Sorry, let me clarify my question a little more. I want to make sure of 2 things.
1) Name property exists in all derived classes
2) Name property is not null or empty
I basically want to force any class that derives from Item (and is not abstract) to have a value for Name.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
听起来您担心初始化属性?
强制设置 Name 属性的一种方法是在基类构造函数中包含此设置器,如下所示:
然后从 MyBaseClass 派生的所有内容都必须满足该构造函数:
然后您还可以使该属性成为:
我不会冒险上面的设计是否良好,但它可以确保所有派生类在实例化时都具有有效的名称属性。
正如其他答案所建议的,另一种方法是实现一个在其基本实现中引发异常的虚拟属性。
It sounds like you are worried about initialising properties?
One way the you can force the Name property to be set is to include this setter in your base class constructor like so:
Then everything that derives from MyBaseClass must satisfy that constructor:
Then you can also make the property either:
I'm not going to venture whether the above is good design, but it would work to ensure that all derived classes have a valid name property when instantiated.
Another approach, as other answers suggest, is to implement a virtual property that throws an exception in its base implementation.
您只需要在基类中定义
Name
,不需要将其指定为抽象。它仍然可以作为所有派生类中的属性使用。You only need to define
Name
in the base class, and do not need to specify it as abstract. It will still be available as a property in all derived classes.那么该对象的名称最终就会变得很愚蠢。
更好的是,让
name
以null
开头。然后,如果您忘记初始化名称但有人尝试使用它,您将收到异常,并且您会知道必须修复它。Then the name of the object will just end up being something silly.
Better yet, have
name
start out asnull
. Then you'll get an exception if you forget to initialize the name but someone tries to use it, and you'll know you have to fix it.迈克是对的,如果您只想在所有派生对象上使用属性“Name”,则根本不需要将其标记为抽象,因为它是继承的。
如果您只想强制执行以下事实:在创建 Item 时,明确设置了名称,您可以通过隐藏零参数构造函数并公开接受该名称的构造函数来强制执行此操作。
看一下这段代码:
上面的定义意味着:
这强制类的任何实例都必须在创建时定义名称。无论如何,一种可能的解决方案......
Mike is right that if you just want to use the property "Name" on all derived objects, you don't need it to be marked abstract at all as it's inherited.
If you want to just force the fact that when Items are created, a name is definitely set, you could force it through hiding the zero-parameter constructor and exposing a constructor that accepts the name.
Take a look at this code:
The above definitions mean that:
This forces that any instance of the classes must define the name at time of creation. One possible solution anyway...
将使 Name 成为虚拟的 ie。
公共虚拟名称 {get;放; }
访问器可以在 Item 类中使用吗?由于头盔和盔甲源自物品类。它将强制要求它们必须被覆盖...希望这会有所帮助,
此致,
汤姆.
Would making Name a virtual ie.
public virtual Name {get; set; }
accessor be used in the Item class? Since Helment and Armor descend from the Item class. It would enforce that they must be overridden...Hope this helps,
Best regards,
Tom.
所以这取决于你想要做什么...
使类抽象强制所有子类实现该类(及其抽象函数等),但是如果你希望一个函数具有可以重写的基本功能那么我建议不要将类设为抽象,而是将特定函数设为虚拟,这样当虚拟函数不被覆盖时,就会调用基函数。
并且总是可以选择创建具有相同名称的“新”属性,但我认为这不是一个好的做法。
希望有帮助。
so it depends what you want to do ...
making class abstract forces all the sub-classes to implement the class (and its abstract functions, etc.), but if you want a function to have a base functionality with the possibility to override the function then i'll suggest not making the class abstract and making the specific function virtual instead, thus when the virtual function is not being overwritten, and base function will be called.
and there's always options to create a "new" properties with the same name, but i don't think that's a good practice.
hope that helps.
我认为您仍然可以在抽象类中使属性虚拟,因此这应该可以解决您的问题。
您可以将该值设置为基抽象类中的特定值,
这是一个例子:
i think you can still make the property virtual within a abstract class, thus that should solve your problem.
You can set the value to something specific in the base abstract class,
here an example :