【发布时间】:2021-03-23 01:41:35
【问题描述】:
我有一个翻译方法,它接收一个类,并将其“升级”为新类型。例如:
class Animal {
public int LegCount {get; set;}
public string Name {get; set;}
}
class FarmAnimal: Animal {
public string Benefit {get; set;}
}
// I get passed the Animal type
var a = new Animal();
a.LegCount = 4;
a.Name = "Cow"
// And I need to upgrade it to a Farm Animal
var b = new FarmAnimal();
b.LegCount = a.LegCount;
b.Name = a.Name;
b.Benefit = "Milk";
但如果开发人员向 Animal 添加了一个新字段,例如 EyeCount,他们将忘记将翻译添加到升级方法中。
我更愿意做的是遍历 Animal 类的属性,并将它们复制到新的 FarmAnimal 类(然后通过我自己的逻辑添加额外的字段)。我只需要复制子类字段。
我希望我可以这样做:
var props = typeof(Animal).GetProperties();
FarmAnimal target = new FarmAnimal ();
foreach (var prop in props)
{
....
}
target.Benefit = "Milk"; // So, I add the extra fields after translating the sub class fields.
但我不确定如何进行实际翻译。如何在 ForEach 中复制每个属性。还是有更好的方法来实现这一点?
编辑:我认为这非常接近,但我需要排除没有 Set 的字段。
var props = typeof(Animal).GetProperties();
FarmAnimal fa = new FarmAnimal();
foreach (var prop in props)
{
typeof(FarmAnimal )
.GetProperty(prop.Name,
BindingFlags.IgnoreCase |
BindingFlags.Instance |
BindingFlags.Public | BindingFlags.SetField)
.SetValue(fa,
prop.GetValue(animal));
}
但我有一些没有设置的属性。
编辑:可能已经找到了。
GetProperties().Where(prop => prop.GetSetMethod() != null)
【问题讨论】:
-
将父级传给子级。
new FarmAnimal(a);并在那里翻译? -
您是否考虑过使用
abstract/virtual属性来制作Animalabstract,而不是使用反射来解决您的问题? -
我根本无法修改 Animal。所以我开始创建一个新类,扩展 Animal。 @RichardBarker - 在这种情况下,我需要在 FormaAnimal 的构造函数中添加翻译?
-
@Craig 是的,这就是我要说的。否则请考虑反思。
-
你可以试试
var set = typeof(FarmAnimal).GetProperty(prop.Name); if(set?.GetSetMethod() != null) set.SetValue(fa, prop.GetValue(animal));
标签: c#