简体   繁体   English

如果对象的引用变量是超类类型,是否可以访问子类的属性?

[英]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. 在这种情况下, FighterArcher会做。

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.

相关问题 如何访问控件类型变量的可能属性? - How do I access a Control type variable's possible properties? 从超类访问子类的类型 - Access the type of a subclass from its superclass 如何使用C#通过超类的引用访问子类变量 - How to access subclass variables through a reference of the superclass with C# C#在对超类对象进行操作时获得对子类变量的访问 - C# Getting access to subclass variable while operating on superclass objects 对象类型变量是引用吗? 还是也可以作为参考? - Is an object-type variable a reference, and that's it? or can it also be a reference to a reference? 使用字符串引用动态比较/访问对象的属性 - Compare/access object's properties dynamically with string reference 当对象属于子类类型时,为什么不能在超类的子类中调用公共方法? - Why can't I call a public method in the subclass from the superclass when the object is of the subclass type? 是否可以通过指向子类对象的父类类型引用变量访问不在父类中的子类成员? - Is it possible to access child class members that are not in parent class from a parent class type reference variable pointing to child class object? 从超类列表中获取子类属性 - Get subclass properties from list of superclass 仅从子类获取超类的属性 - Get only the properties of the superclass from subclass
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM