我经常写这样的课程:
public class Animal
{
public string Colour { get; set; }
public int Weight { get; set; }
public Animal(Dog data)
{
this.Colour = data.Colour;
this.Weight = data.Weight;
}
public Animal(Cat data)
{
this.Colour = data.Colour;
this.Weight = data.Weight;
}
}
如果你有很多属性和类型,那么你很快就会得到很多锅炉板代码。理想情况下,在这种情况下,我只需创建一个IAnimal接口并引用它。我目前处于第三方程序集中存在Dog和Cat类的情况,我无法修改它们。我能想出的唯一解决方案是:
public class Animal
{
public string Colour { get; set; }
public int Weight { get; set; }
public Animal(Cat data){Init(data);}
public Animal(Dog data){Init(data);}
private void Init(dynamic data)
{
this.Colour = data.Colour;
this.Weight = data.Weight;
}
}
这有效但我失去了所有类型的安全性,是否有比构造函数注入更好的解决方案?
谢谢,
乔
编辑:这是一个真实世界的例子。我有一个第三方库,它返回3个名为:的对象(这些都是来自服务引用的自动生成的类,并且属性非常相似)
我想要处理单个PageData对象或它们的集合,而不是处理这三个对象。
答案 0 :(得分:3)
您可以在一个所有其他构造函数调用的公共构造函数中使用逻辑:
public class Animal
{
public string Colour { get; set; }
public int Weight { get; set; }
public Animal(Dog data) : this (data.Colour, data.Weight)
{
}
public Animal(Cat data) : this (data.Colour, data.Weight)
{
}
private Animal(string colour, int weight)
{
this.Colour = colour;
this.Weight = weight;
}
}
这与您的第二个解决方案非常相似,但它不会失去类型安全性。
答案 1 :(得分:3)
我目前处于
Dog
和Cat
类存在的情况 第三方组装,我不能修改它们
我建议使用基于Automapper的解决方案:
public static class AnimalFactory
{
public static Animal Create<T>(T source)
where T : class
{
Mapper.CreateMap<T, Animal>();
return Mapper.Map<Animal>(source);
}
}
用法:
var catAnimal = AnimalFactory.Create(cat);
var dogAnimal = AnimalFactory.Create(dog);
当然,如果需要,您可以提供自定义映射配置的方法。
答案 2 :(得分:1)
如果你不想让这类课程乱丢,你可以试试扩展方法吗?
public static Animal ToAnimal(this Dog item)
{
return new Animal() {Weight = item.Weight, Colour = item.Colour};
}
public static Animal ToAnimal(this Cat item)
{
return new Animal() {Weight = item.Weight, Colour = item.Colour};
}
答案 3 :(得分:0)
尝试使用json序列化程序,我们可以确保类型安全。
public class Animal
{
public string Colour { get; set; }
public long Weight { get; set; }
public string Name { get; set; }
public Animal Create<T>(T anyType)
{
return GetObject<T, Animal>(anyType);
}
public K GetObject<T, K>(T type1)
{
try
{
var serialized = JsonConvert.SerializeObject(type1);
return JsonConvert.DeserializeObject<K>(serialized);
}
catch (Exception ex)
{
return default(K);
}
}
}
class Program
{
public static void Main(string[] args)
{
Animal obj = new Animal();
var animal = obj.Create(new { Colour = "Red", Weight = 100 });
//here you can pass any object, only same name properties will be initialized..
Console.WriteLine(animal.Colour + " : " + animal.Weight);
Console.ReadKey();
}
}