[英]Is it possible to access properties of a subclass if the object's reference variable is a superclass type?
I am new to programming and to c# and I just wanna know if there is a way for me to initialize the subclass fields through property if my reference variable is a superclass type. 我是编程和C#的新手,我只是想知道如果我的引用变量是超类类型,是否可以通过属性初始化子类字段。
Example 例
Character test = new Archer();
test.Damage = 5; // Damage is from the Fighter Class
SuperClass Character 超类人物
abstract class Character
{
//Superclass common
}
Class Fighter subclass of Character 角色的 Class Fighter子类
abstract class Fighter : Character
{
private int damage
public int Damage {
get
{
return damage;
}
set
{
damage = value;
}
}
}
Class Archer subclass of Fighter 战士的 弓箭手类
class Archer : Fighter
{
//stuffs that only archers can do
}
I am new to programming and to c#
我是编程和C#的新手
Welcome aboard. 欢迎上车。 Let me start by encouraging you to get a good book, take a course, get a tutor, or whatever you do to learn a subject.
首先,我要鼓励您获得一本好书,上一门课程,找一位导师,或者您为学习一门学科所做的一切。 StackOverflow is explicitly not a tutorial site .
StackOverflow显然不是教程站点 。
is there is a way for me to initialize the subclass fields through property if my reference variable is a superclass type?
如果我的引用变量是超类类型,是否可以通过属性初始化子类字段?
The beginner programmer answer is: no. 初学者程序员的答案是:不。
If you want to access a property of a more-derived type then the reference you have in hand has to be known to be of that more-derived type. 如果要访问派生类型更大的属性,则必须知道您手头的引用属于该派生类型。
C# is what we call a "statically typed" language, meaning that there has to be "static" -- that is, known to the compiler -- type information that demonstrates that each expression is valid. C#是我们所谓的“静态类型”语言,这意味着必须有“静态”(即编译器已知)类型信息,以证明每个表达式都是有效的。
The advanced programmer answer is: yes, but do not do it. 程序员的高级答案是:是的,但是不要这样做。
C# has a "dynamic" mode; C#具有“动态”模式; if you said
如果你说
dynamic test = new Archer();
test.Damage = 123;
That would work. 那行得通。 Do not do this .
不要这样做 。 Two reasons.
有两个原因。 First, if you turn off static type checking, static type checking is turned off .
首先, 如果您关闭静态类型检查 , 则会关闭静态类型检查 。 You could write
你可以写
dynamic test = new Archer();
test.Damaeg = 123;
and the compiler would allow it, and your program would crash at runtime. 并且编译器会允许它,并且您的程序将在运行时崩溃。 Static type checking is there to help you.
静态类型检查可以为您提供帮助。 Use it.
用它。
Second, we added dynamic
so that people could write C# programs that interact with dynamic languages such as Python and JavaScript. 其次,我们添加了
dynamic
以便人们可以编写与动态语言(例如Python和JavaScript)进行交互的C#程序。 Use it for that, when you need to, not as an end-run around static type checking. 为此,在需要时,请勿将其用作静态类型检查的最终结果。
Should I use the most specific class instead?
我应该使用最具体的课程吗?
You should use a specific enough class. 您应该使用足够具体的类。 In this case,
Fighter
or Archer
would do. 在这种情况下,
Fighter
或Archer
会做。
While we are looking at your code, a few other comments: 在查看您的代码时,还有其他一些评论:
private int damage
public int Damage {
get
{
return damage;
}
set
{
damage = value;
}
That is correct, but that is how you'd write it in C# 1.0. 没错,但这就是您在C#1.0中编写它的方式。 In any version of C# from 3.0 on, you would typically write the much shorter form:
从3.0以后的任何版本的C#中,您通常都会编写简短得多的形式:
public int Damage { get; set; }
and let the compiler manage the backing field for you. 并让编译器为您管理后备字段。
Consider also: *do you want the Damage
property to be settable outside of the class hierarchy? 还请考虑:*您是否希望可以在类层次结构之外设置
Damage
属性? If the answer is "no" then make it a protected set;
如果答案为“否”,则将其
protected set;
否则,将其protected set;
property. 属性。 Do you want it to be settable outside of the
Fighter
class? 您是否希望可以在
Fighter
类之外设置它? If no, make it private set;
如果否,则将其
private set;
Do you want it to be settable at all after it is initially set? 您是否希望它在初始设置后就可以设置? If no, then (in C# 7) omit the
set
entirely and it will be only settable in the constructor. 如果没有,则(在C#7中)完全省略该
set
并且只能在构造函数中设置。
Also, this is probably too advanced for you right now, but it may also stop you from going down a bad path. 另外,这可能对您来说现在太先进了,但它也可能使您走上一条艰难的道路。 I wrote a series of articles specifically about the problem space you are exploring, and common pitfalls that even advanced programmers fall into.
我写了一系列文章,专门讨论您正在探索的问题空间,以及即使是高级程序员也可能遇到的常见陷阱。 It starts here: https://ericlippert.com/2015/04/27/wizards-and-warriors-part-one/ -- I talk more about abusing
dynamic
in that series as well. 它从这里开始: https : //ericlippert.com/2015/04/27/wizards-and-warriors-part-one/-我也更多地讨论了该系列中的滥用
dynamic
。
Answering your question, you can set the value, you just have to cast before: 回答您的问题,您可以设置值,只需在执行以下操作之前进行强制转换:
(test as Archer).Damage = 5;
//Or
//(test as Fighter).Damage = 5;
Now, if you should do that, check Eric's answer and his blog. 现在,如果您应该这样做,请查看Eric的答案和他的博客。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.