简体   繁体   English

如何从基类实例访问派生类属性

[英]How to access derived class properties from base class instance

I have the following code which I can't access or change:我有以下代码无法访问或更改:

class A{
}

class B:A{
    string name;
    int age;
    string desc;
}

class C:A{
    string name;
    int age;
    string desc;
}

I need to find a way to write a function that assigns values to instances of B and C. the naive way would be to write two functions.我需要找到一种方法来编写一个函数,为 B 和 C 的实例赋值。最简单的方法是编写两个函数。 one for each class.每个班级一个。

void myFunc(B b){
    b.name = "some_name";
    b.age = 27;
    b.desc = "some_desc";
}

void myFunc(C c){
    c.name = "some_name";
    c.age = 27;
    c.desc = "some_desc";
}

Is there a way to write one generic function that those the job?有没有办法编写一个通用函数来完成工作? of-course those classes are only examples.当然,这些课程只是示例。 In the real world there are many classes deriving from the base class and each class has many members.在现实世界中,从基类派生出许多类,每个类都有许多成员。

We can find several ways to do this.我们可以找到几种方法来做到这一点。 For example you can use an extension method for the type: A And use reflection to set fields in it.例如你可以对类型使用一个扩展方法: A 并使用反射来设置其中的字段。

Like this:像这样:

public static class ClassExtensions
{
    public static void SetProperties(this A a, string name, int age, string desc)
    {
        Type type = a.GetType();
        type.GetField("name")?.SetValue(a, name);
        type.GetField("age")?.SetValue(a, age);
        type.GetField("desc")?.SetValue(a, desc);
    }
}

Here is how it works: https://dotnetfiddle.net/9uR3bA这是它的工作原理: https : //dotnetfiddle.net/9uR3bA

Or just use dynamic like:或者只是使用动态,如:

public static void Main(string[] args)
{
    var b = new B();
    SetValues(b, "yes", 5, "ok");

    var c = new C();
    SetValues(c, "no", 10, "not ok");
}

public static void SetValues(dynamic theClass, string name, int age, string desc)
{
    theClass.name = name;
    theClass.age = age;
    theClass.desc = desc;
}

Note: I'm assuming the fields or properties will be public, not private.注意:我假设字段或属性是公开的,而不是私有的。

Just curious: why not using Automapper ?只是好奇:为什么不使用Automapper It uses a convention-based approach, and when that's not enough, you can write the mapping code yourself and inject it.它使用基于convention-based方法,当这还不够时,您可以自己编写映射代码并注入它。

That's not a good design.这不是一个好的设计。 If you can in any way change it, strongly consider doing so, but if you can't, here's what you can do.如果你能以任何方式改变它,强烈考虑这样做,但如果你不能,这就是你可以做的。

You don't need Reflection for this.为此,您不需要反射。 Downcasting will do the job: 向下转换将完成这项工作:

void MyMethod(A a)
{
    if (a is B b)
    {
        b.name = "some_name";
        b.age = 27;
        b.desc = "some_desc";        
    }

    if (a is C c)
    {
        c.name = "some_name";
        c.age = 27;
        c.desc = "some_desc";
    }
}

Since A is an unsealed base class, other derived classes could exist ( class D : A etc.), but since MyMethod doesn't return anything, passing any other subtype as an argument is simply going to be a no-op.由于A是未密封的基类,因此可能存在其他派生类( class D : A等),但由于MyMethod不返回任何内容,因此将任何其他子类型作为参数传递只是无操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM