在“从基继承的类”中设置字段的值

本文关键字:设置 字段 继承 | 更新日期: 2023-09-27 18:32:03

我认为这很容易,但我不知道如何:)

class base1
{
    public int x = 1;
//... many other fields
}
class inherit1:base1
{
    int y = 5;
  ...
}
base bs=new base1();
// set many fields value of the bs class
bs.value1=5;
bs.value15="sss";
//....set other fileds values
inherit1 i1=new inherit1(); 
将所有字段值

继承的类 I1 设置为等于基本字段值 BS 的最快方法是什么?
我想做这样的事情:

i1=bs;

并在初始化所有其他字段 i1 之后。

谢谢!

在“从基继承的类”中设置字段的值

不能只将基类意向分配给派生类型。您需要转换它。

所以,你的第一个选择是使用 AutoMapper .它可以帮助您将数据从对象类型复制到其他对象类型。它将自动映射具有相同名称的属性。最后,您将使用以下代码 f.e:

var derived = Mapper.Map<Base, Derived>(b);


第二个选择是编写方法并使用反射。

并在构造函数中使用它:

public class Derived : Base
{
    public Derived(Base b)  
    {
        SetProperties(b);
    }
    private void SetProperties(object mainClassInstance)
    {
        var bindingFlags = BindingFlags.Public | BindingFlags.Instance;
        var mainClassType = mainClassInstance.GetType();
        MemberInfo[] members = mainClassType.GetFields(bindingFlags).Cast<MemberInfo>()
            .Concat(mainClassType.GetProperties(bindingFlags)).ToArray();
        foreach (var memberInfo in members)
        {
            if (memberInfo.MemberType == MemberTypes.Property)
            {
                var propertyInfo = memberInfo as PropertyInfo;
                object value = propertyInfo.GetValue(mainClassInstance, null);
                if (null != value)
                    propertyInfo.SetValue(this, value, null);
            }
            else
            {
                var fieldInfo = memberInfo as FieldInfo;
                object value = fieldInfo.GetValue(mainClassInstance);
                if (null != value)
                    fieldInfo.SetValue(this, value);
            }
        }
    }
}

然后你只需要:

Base b = new Base {...};
Derived d = new Derived(b);

此外:

实际上,将SetProperties方法作为扩展方法会更好。

public static class ObjectExtensions
{
    public static void SetProperties(this object newClassIntance, object mainClassInstance)
    {
        var bindingFlags = BindingFlags.Public | BindingFlags.Instance;
        var mainClassType = mainClassInstance.GetType();
        MemberInfo[] members = mainClassType.GetFields(bindingFlags).Cast<MemberInfo>()
            .Concat(mainClassType.GetProperties(bindingFlags)).ToArray();
        foreach (var memberInfo in members)
        {
            if (memberInfo.MemberType == MemberTypes.Property)
            {
                var propertyInfo = memberInfo as PropertyInfo;
                object value = propertyInfo.GetValue(mainClassInstance, null);
                if (null != value)
                    propertyInfo.SetValue(newClassIntance, value, null);
            }
            else
            {
                var fieldInfo = memberInfo as FieldInfo;
                object value = fieldInfo.GetValue(mainClassInstance);
                if (null != value)
                    fieldInfo.SetValue(newClassIntance, value);
            }
        }
    }
}

然后,您可以将此方法用作:this.SetInheritedProperties(b);

在 C# 中,将引用分配给另一个像 i1=bs; 实际上是使引用 i1 引用 base1 对象,这意味着 inheret1 将不再被引用并准备好进行垃圾回收。

另一个问题是i1=bs;会导致语法错误,因为不能将对基类的引用分配给对派生类的引用,只允许相反的情况。

我想你追求的是克隆。

使 base1 实现 IClonable 接口,并在 base1 和 inheret1 类中实现克隆方法。

现在,不要使用 i1=bs; 来复制对象,而是使用 b2 = (base1)b1。克隆();将 base1 对象复制到另一个对象。

为了能够将 base1 对象复制到 inheret1 对象

,您需要创建一个 inheret1 的构造函数,该构造函数采用 base1 对象并复制所有成员(甚至更好的是从 base1 到 inheret1 的显式或隐式转换器)。

您要将值从bs复制到i1?您不需要这样做,因为 inherit1 的构造函数将自动从base1调用该构造函数,因此将为您初始化相同的值。

考虑一下:

class base1
{
    public int x = 1;
    public int y = 1;
}
class inherit1:base1
{
    int z = 5;
  ...
}
base bs=new base1();
// bs now has x = y = 1    
inherit1 i1=new inherit1(); 
// inherit1 also has x = y = 1, and z = 5

您现在可以调用将返回1i1.x

但是,如果您已经有一个 base 实例并希望将其转换为 inherit1 的实例,则必须提供一些复制逻辑,例如:

class inherti1 : base1 {
    public inherit1(base1 b) {
        this.x = b.x;
        this.y = b.y;
        this.z = 6;
    }
}