【问题标题】:copying value of object a to object b without disturbing not null value in c#将对象a的值复制到对象b而不干扰c#中的非空值
【发布时间】:2015-12-22 16:59:54
【问题描述】:

我有两个相同类的对象说 Obj1 和 Obj2 如果相同的 class.Obj1 包含一些值而其他的相同。 例如

class book 
{
   public string science {get;set;} 
   public string math {get;set;}
   public string drawing {get;set;}
   public string english {get;set;}
}

Obj1 包含绘图、数学和科学价值。
Obj2 包含数学和英语值。

我想以这样的方式将 Obj1 复制到 Obj2,这样 Obj2 就可以获取绘图、科学值,并在 Obj1 中按值替换数学值,并且还保留 Obj2 的英文值。

这只是示例真实项目,在类中包含 60 多个属性,所以我不想像 Obj2.drawing=Obj1.drawing,Obj2.math=Obj1.math 那样做。我需要这样做而不提属性名称,如数学、绘图......


总而言之,我需要将 Obj1 的值复制到 Obj2 中,并且只有 Obj1 中的值在 Obj2 中替换,Obj1 的空值不应替换 Obj2 中的值。 这可能吗?如果是,请指导我。

【问题讨论】:

  • 也许你的班级设计需要改变。尝试使用Dictionary
  • 您有几种方法可以做到这一点。你有什么烦恼?如果您展示您的尝试,也许我们可以提供更好的帮助

标签: c# object


【解决方案1】:

自动映射到resque!

Mapper.CreateMap<Book, Book>()
    .ForAllMembers(opt => opt.Condition(srs => !srs.IsSourceValueNull));

var b1 = new Book { P1 = null, P2 = "b1p2" };
var b2 = new Book { P1 = "b2p1", P2 = "b2p2" };

Mapper.Map(b1, b2);

Assert.IsNotNull(b2.P1);

【讨论】:

  • Mapper 表示 i 的来源
  • @ConfuseD,抱歉,我无法解析你的评论,你能重新表述一下吗?
【解决方案2】:

您可以为此使用 System.Reflection。但它很慢,比 obj2.drawing = obj1.drawing 慢得多。这是代码:

    public static void CopyNotNulls<T>(T source, T dest)
    {
        var type = typeof(T);
        var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance)
            .Where(p => p.PropertyType.IsClass)
            .ToArray();
        foreach (var property in properties)
        {
            var val = property.GetValue(source);
            if (val == null)
            {
                continue;
            }
            property.SetValue(dest, val);
        }
    }

【讨论】:

  • 您是否将using System.Reflection; 添加到您的cs 文件中?
  • 还是使用值类型(定义为struct { }
【解决方案3】:

您可以有一个基于实例的复制函数,在分配值之前检查 null:

public class book
{
    public string science { get; set; }
    public string math { get; set; }
    public string drawing { get; set; }
    public string english { get; set; }

    public book()
    {
    }

    public void CopyTo(book other)
    {
        if (!string.IsNullOrEmpty(this.science))
            other.science = this.science;

        if (!string.IsNullOrEmpty(this.math))
            other.math = this.math;

        if (!string.IsNullOrEmpty(this.drawing))
            other.drawing = this.drawing;

        if (!string.IsNullOrEmpty(this.english))
            other.english = this.english;
    }
}

例子:

var foo = new book();
foo.science = "foo1";
foo.math = "foo2";
foo.drawing = "foo3";
foo.english = null;

var bar = new book();
bar.science = "bar1";
bar.math = "bar2";
bar.drawing = "bar3";
bar.english = "bar4";

foo.CopyTo(bar);

Console.WriteLine(bar.science);
Console.WriteLine(bar.math);
Console.WriteLine(bar.drawing);
Console.WriteLine(bar.english);

Console.Read();

这将确保属性foo.englishnull 值不会复制到bar obj 的关联属性中。

给出输出:

foo1 foo2 foo3 酒吧4

【讨论】:

  • CopyTo 无法识别
  • 那么我必须检查 !string.IsNullOrEmpty 是否有所有属性太长
  • 什么意思“不认识”?你把它添加到你的book 班级了吗?如果您的 OP 中的课程只是一个示例,您应该在问题中说明,我不知道您要做什么。
【解决方案4】:

您可以改用字典。它有这些方法:

Add(String key, String value)
TryGetValue(String key, out String value)

您也可以像数组一样使用它们,只需将字符串放在方括号中即可。

String x = dictionary["x"];

你可能想做的一个例子:

var books = new Dictionary<String, String>();
books.Add("Science", "Sciencey stuff goes in here!");
books.Add("English", "How now brown cow");
Console.WriteLine(books["English"]);

// Now lets assume you want to add one set of books to another
foreach(KeyValuePair<String, String> book in books1)
    if (!books2.ContainsKey(book.Key))
        books2.Add(book.Key, book.Value);

【讨论】:

    【解决方案5】:
    class book 
    {
       public string science {get;set;} 
       public string math {get;set;}
       public string drawing {get;set;}
       public string english {get;set;}
    }
    

    假设你有 Obj1Obj2 喜欢:

    var Obj1 = new book() { science = "molecules", math = "sin(x)", drawing = "brush" };
    var Obj2 = new book() { math = "cos(y)", english = "Shakespeare" };
    

    首先,您必须获得Obj1 的所有属性。然后读取for 循环中每个属性的值,将其保存在ValueRead 变量中。检查ValueRead是否不是null,然后将其复制到Obj2

    foreach (PropertyInfo propertyInfo in Obj1.GetType().GetProperties())
    {
        var ValueRead = Obj1.GetType().GetProperty(propertyInfo.Name).GetValue(Obj1, null);
        if (ValueRead != null)
            Obj2.GetType().GetProperty(propertyInfo.Name).SetValue(Obj2, ValueRead, null);
    }
    

    Obj2 会像:

    {science = "molecules", math = "cos(y)", drawing = "brush", english = "Shakespeare" }
    

    【讨论】:

      猜你喜欢
      • 2017-11-25
      • 1970-01-01
      • 1970-01-01
      • 2017-11-23
      • 1970-01-01
      • 1970-01-01
      • 2016-04-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多