有没有办法比较两个不同结构的两个实例,如果有完全相同名称的属性,是否将它们从一个实例复制到另一个实例?
例如,取两个结构:
struct typeA
{
public byte ID;
public byte distance;
public byte time;
}
struct typeB
{
public byte distance;
public byte length;
}
然后创建变量
typeA A;
typeB B;
接下来分配了一些值
A.ID = 101;
A.distance = 12;
A.time = 5;
现在我想比较变量A和B,如果有任何具有相同名称的属性(在这种情况下,两个struct都存在'distance')将它们复制到另一个变量。 我不想用
B.distance = A.distance
因为我不会总是知道属性的名称。
有人有什么想法吗?只听说过反思,有什么要看的吗?
答案 0 :(得分:3)
我建议您使用映射工具。例如。 AutoMapper(来自NuGet)
Mapper.CreateMap<typeA, typeB>();
typeA A = new typeA { ID = 101, distance = 12, time = 5 };
typeB B = new typeB { length = 42 };
// ...
B = Mapper.Map(A, B);
使用默认映射,AutoMapper将映射具有相同名称的属性。
您应该将映射结果分配回B
变量,因为结构是值类型并且它们是按值传递的。因此,对B
的已通过副本的更改不会影响原始B
变量。上面代码的结果是变量B
,其值为:
{
distance: 12,
length: 42
}
答案 1 :(得分:1)
请注意,您所说的是属性,但您的示例代码定义了字段而不是属性。以下扩展方法复制字段:
public static class Extensions
{
public static void MergeFrom<TSource, TDestination>(this TDestination dest, TSource source)
{
var fieldPairs = typeof(TDestination)
.GetFields()
.Join(
typeof(TSource).GetFields(),
p => p.Name,
a => a.Name,
(bp, ap) => new { Source = bp, Destination = ap });
foreach (var pair in fieldPairs)
{
pair.Destination.SetValue(dest, pair.Source.GetValue(source));
}
}
}
答案 2 :(得分:0)
你应该利用AutoMapper。
然后您可以通过以下方式使用它:
Mapper.CreateMap<typeA, typeB>();
如果您想为映射过程设置一些其他规则,可以采用以下方式执行此操作:
Mapper.CreateMap<typeA, typeB>()
.ForMember(dest => dest.a, opt => opt.MapFrom(src => src.b));