减少构造函数锅炉板代码

时间:2015-08-20 12:42:14

标签: c#

我经常写这样的课程:

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个名为:

的对象
  • GetPageByIdResult
  • GetPagesByParentIdResult
  • GetPagesByDateResult

(这些都是来自服务引用的自动生成的类,并且属性非常相似)

我想要处理单个PageData对象或它们的集合,而不是处理这三个对象。

4 个答案:

答案 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)

  

我目前处于DogCat类存在的情况   第三方组装,我不能修改它们

我建议使用基于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();
        }
    }