C# 设置字段';从基类继承的类中的s值

C# 设置字段';从基类继承的类中的s值,c#,C#,我认为这很容易,但我不知道怎么做:) 将继承类i1的所有字段值设置为基字段值bs的最快方法是什么? 我想这样做: i1=bs; 在init之后是所有其他字段i1 谢谢! 是否要将值从bs复制到i1?您不需要这样做,因为inherit1的构造函数将自动从base1调用该构造函数,因此将为您初始化相同的值 考虑这一点: class base1 { public int x = 1; public int y = 1; } class inherit1:base1 { in

我认为这很容易,但我不知道怎么做:)

将继承类i1的所有字段值设置为基字段值bs的最快方法是什么?
我想这样做:

i1=bs;
在init之后是所有其他字段i1


谢谢!

是否要将值从
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
现在可以调用
i1.x
,它将返回
1

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

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

不能只将基类intance分配给派生类型。你需要转换它

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

var derived = Mapper.Map<Base, 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);
            }
        }
    }
}
公共静态类ObjectExtensions
{
公共静态void SetProperties(此对象为NewClassInstance,对象为mainClassInstance)
{
var bindingFlags=bindingFlags.Public | bindingFlags.Instance;
var mainClassType=mainclasinstance.GetType();
MemberInfo[]members=mainClassType.GetFields(bindingFlags.Cast())
.Concat(mainClassType.GetProperties(bindingFlags)).ToArray();
foreach(成员中的var memberInfo)
{
if(memberInfo.MemberType==MemberTypes.Property)
{
var propertyInfo=memberInfo作为propertyInfo;
对象值=propertyInfo.GetValue(mainClassInstance,null);
if(null!=值)
propertyInfo.SetValue(newClassInstance,value,null);
}
其他的
{
var fieldInfo=作为fieldInfo的memberInfo;
对象值=fieldInfo.GetValue(mainClassInstance);
if(null!=值)
fieldInfo.SetValue(newClassIntance,value);
}
}
}
}
然后,您可以将此方法用作:
this.SetInheritedProperties(b)

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

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

我猜你想要的是克隆

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

现在不再使用
i1=bs
对于复制对象,使用b2=(base1)b1.Clone();将base1对象复制到另一个对象


为了能够将base1对象复制到inheret1对象,您需要创建inheret1的构造函数,该构造函数接受base1对象并复制所有成员(或者更好地创建一个从base1到inheret1的显式或隐式转换器)。

您能进一步说明这一点吗。。?给我们一个你想做什么的例子?在这个问题上很难找到您的目标我需要将所有字段值继承类设置为等于基类字段值…您想将值从
bs
复制到
inherit1
?您无需执行此操作,因为
inherit1
的构造函数将自动从
base
调用该构造函数,因此将为您初始化相同的值。否,基类字段值不等于构造函数中的初始化值,它使用较早,并且在构造函数中具有字段值,而不是初始化值。我需要将继承类的所有字段设置为相等的基…我认为您想要克隆--深度复制--一个对象。这是C#中的一个已知问题,可以用不同的方法解决,但没有一种方法是完美的。(C++有一个更好的方法,imho。)其中之一:您可能想看看
Object.MemberwiseClone()
,它只是复制所有字段,并且可以作为您自己的
DeepClone()
函数的开始。对于Int、float、structs等值字段,这意味着您将收到一个真正的副本——使用tem还能做什么?对于引用类型,它只复制引用,这对于不可变类型来说已经足够了。对于可变类型,您必须深入复制自己。谢谢。这很简单,但基类有很多字段,我希望有一种复制字段值的其他方法,还有一件事-基类可能会改变,然后我需要改变派生类的复制逻辑…唯一的解决方法是使用Fahrad建议的反射,这是正确的方法!谢谢,只有在我的情况下,FieldInfo(而不是propertyInfo)@Bааааааааааааааааааа107。别忘了你可以将此标记为答案。@Бааааааааааааа107。现在,它将同时支持属性和字段。
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);
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);
            }
        }
    }
}