【问题标题】:Assignment same property values to other将相同的属性值分配给其他
【发布时间】:2020-01-01 06:37:15
【问题描述】:

我有不同的类共享一些相同类型和名称的属性。我希望彼此分配相同的属性值。我在下面的伪代码中用 cmets 更好地解释了我的意图。在 C# 中可以吗?

想一想,有很多共同的属性,但在不相关的类中,我们是否必须一一分配它们?

第二种情况是共享相同的属性,但其中一些可能是空的,谁知道呢!

旁注:类已经存在,无法更改,无法触摸。有点像sealed

不能使用nameofoperator 和两个for循环来完成吗?如果匹配,比较属性名称,分配?

using System;

namespace MainProgram
{
    class HomeFood
    {
        public DateTime Date         { get; set; }
        public string   food1        { get; set; }
        public string   food2        { get; set; }
        public int      cucumberSize { get; set; }
    }

    class AuntFood
    {
        public string   food2        { get; set; }
        public int      cucumberSize { get; set; }
        public DateTime Date         { get; set; }
        public string   food1        { get; set; }
        // extra
        public double? length { get; set; }
    }

    class GrandpaFood
    {
        public string?   food2        { get; set; }
        public int      cucumberSize { get; set; }
        public DateTime? Date         { get; set; }
        public string   food1        { get; set; }
        // extra
    }


    static class Program
    {
        public static void Main(string[] args)
        {
            var home = new HomeFood
                       {
                           Date         = new DateTime(2020, 1, 1),
                           food1        = "cucumber",
                           food2        = "tomato",
                           cucumberSize = 123
                       };

            var aunt = new AuntFood();

            /*
             First case: same types
             Expected for-each loop 
             assigning a class's property values 
             to other class's property values

             or for-loop no matter
             foreach(var property in HomeFood's properties)
                assign property's value to AuntFood's same property
             */

            var home2 = new HomeFood();
            var grandpa = new GrandpaFood
                       {
                           Date         = new DateTime(2020, 1, 1),
                           food1        = "dfgf",
                           food2        = "dfgdgfdg",
                           cucumberSize = 43534
                       };

            /*
             Second case: similar to first case
             with the exception of same type but nullable

             or for-loop no matter
             foreach(var property in GrandpaFood's properties)
                assign property's value to GrandpaFood's same property
                we don't care if it is null e.g.
                Home2's same property = property's value ?? default;
             */

        }
    }
}

【问题讨论】:

  • 为什么不使用枚举属性 FoodType 创建一个类 Food
  • automapper 可以帮你做到这一点
  • @Charles 该示例仅用于说明目的。想一想你有不同的sql列,用属性表示,涉及到生成的两个不同的类,不能碰,能不能提出你的枚举思路?
  • @snr 我也建议使用 automapper,但如果您不想使用库,也可以使用反射实现同样的效果
  • @gsharp 不能用nameof操作符和两个for循环来完成吗?如果匹配,比较属性名称,分配?

标签: c# .net class oop foreach


【解决方案1】:

根据问题中的 cmets,这只是为了说明如何通过反射来完成。

免责声明,这只是一个关于如何使用反射来同步属性的非常简化的示例。它不处理任何特殊情况(修饰符、只读、类型不匹配等)

我强烈建议使用 automapper 来实现 qp 目标。

public class Type1
{
    public string Property1 { get; set; }
    public string Property2 { get; set; }
}

public class Type2
{
    public string Property1 { get; set; }
    public string Property3 { get; set; }
}


class Program
{
    static void Main(string[] args)
    {

        var t1 = new Type1 { Property1 = "Banana" };
        var t2 = new Type2();

        var properties1 = typeof(Type1).GetProperties().ToList();
        var properties2 = typeof(Type2).GetProperties().ToList();

        foreach(var p in properties1)
        {
            var found = properties2.FirstOrDefault(i => i.Name == p.Name);
            if(found != null)
            {
                found.SetValue(t2, p.GetValue(t1));
            }
        }

        Console.WriteLine(t2.Property1);
    }
}

【讨论】:

    【解决方案2】:

    简短的回答是,应用 OOP。定义一个基类 Food 并在您拥有的任何特定食物类中从它继承。您可以将所有共享道具放在基类中。

    public class Food 
    {
       public string   food2  { get; set; }
       // other shared stuff
    }  
    
    class GrandpaFood : Food
    {
       // other specific stuff
    }
    

    【讨论】:

    • 请考虑我的旁注(:
    • 那么就像cmets中的建议,你可以使用automapper。但我会尝试改变课程。蚀刻中没有什么是石头,你知道 :)
    【解决方案3】:

    正如其他人所说,使用一些面向对象的属性,例如继承实现接口的超类。

    如果您选择继承,请考虑将超类(您从中继承的那个)抽象化。这意味着超类本身不能被实例化,这大大降低了违反里氏替换原则的风险。它也常常能更好地反映实际问题。在您的示例中,情况也是如此,因为“食物”不是现实世界中的实际事物,而是一组事物。

    【讨论】:

      猜你喜欢
      • 2011-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-04
      • 1970-01-01
      • 2020-06-24
      • 2018-11-03
      • 1970-01-01
      相关资源
      最近更新 更多