NET:如何在具有相似成员(类型和名称)的不同类之间复制数据

本文关键字:同类 数据 复制 之间 类型 成员 相似 NET | 更新日期: 2023-09-27 18:22:02

假设我们有两个类:

public class A
{
  public int P1 {set; get;}
  public int P2 {set; get;} 
}
public class B
{
  public int P1 {set; get;}
  public int P2 {set; get;}
  public int P3 {set; get;}
  public int P4 {set; get;} 
}

我可以用某种方式转换它以初始化具有相同名称的成员吗?

我的意思是,如果.NET有一些东西可以排除操作,比如:

A.P1 = B.P1
A.P2 = B.P2
B.P1 = A.P1
B.P2 = A.P2

并忽略其他成员。。。

有可能做到吗?

NET:如何在具有相似成员(类型和名称)的不同类之间复制数据

您可以提取接口的公共属性。

public interface IMyInterface
{
  int P1 {set; get;}
  int P2 {set; get;}
}
public class A : IMyInterface
{
  public int P1 {set; get;}
  public int P2 {set; get;} 
}
public class B : IMyInterface
{
  public B(IMyInterface i)
  {
    P1 = i.P1;
    P2 = i.P2;
  }
  public int P1 {set; get;}
  public int P2 {set; get;}
  public int P3 {set; get;}
  public int P4 {set; get;} 
}

然后你可以这样做:

A a = new A();
a.P1 = 1;
a.P2 = 2;
B b = new B(a);
Console.WriteLine(b.P1); //Outputs 1
Console.WriteLine(b.P2); //Outputs 2

编辑:也许你可以看看https://github.com/AutoMapper/AutoMapper库

如果您拥有并可以更改类A和B,则使用接口或继承都是有效的解决方案。

如果不这样做,可以使用"反射"将属性从一个对象复制到另一个对象。类似上面的

A a = new A();
B b = new B();
GenericConverter<A,B>.Convert(a, b);

public static class GenericConverter<TInput, TOutput> where TOutput : new()
{
    /// <summary>
    /// Converts <paramref name="entity"/> from <see cref="TInput"/> to <see cref="TOutput"/>
    /// </summary>
    /// <param name="entity">the object to convert</param>
    /// <returns>The object converted</returns>
    public static TOutput Convert(TInput entity)
    {
        if(entity is Enum)
            throw new NotImplementedException("Entity is an enumeration - Use ConvertNum!");
        TOutput output = new TOutput();
        Type fromType = entity.GetType();
        Type toType = output.GetType();
        PropertyInfo[] props = fromType.GetProperties();
        foreach (PropertyInfo prop in props)
        {
            PropertyInfo outputProp = toType.GetProperty(prop.Name);
            if (outputProp != null && outputProp.CanWrite)
            {
                string propertyTypeFullName = prop.PropertyType.FullName;
                object value = prop.GetValue(entity, null);
                outputProp.SetValue(output, value, null);
            }
        }
        return output;
    }
}

由于类之间没有继承关系,因此不能将一个类强制转换为另一个类。

如果B继承自A,则可以执行此操作,然后它将自动获取在A上定义的属性。

关于你的例子:

A.P1 = B.P1
A.P2 = B.P2
B.P1 = A.P1
B.P2 = A.P2

由于所有P1P2成员的类型都是int,所以您总是可以进行这样的赋值,因为属性是公共的,并且具有公共getter和setter。不需要铸造。

你为什么想要这样的东西?如果两个类彼此相关,您可能希望继承它们:

public class A
{
  public int P1 {set; get;}
  public int P2 {set; get;} 
}
public class B : A
{
  public int P3 {set; get;}
  public int P4 {set; get;} 
}