2012-11-03 19 views
5

लगता है मैं एक ही वस्तुओं, O1, और O2 के 2 उदाहरणों की है। अगर मैंपाश और रिक्त नहीं गुण

if (o1.property1 != null) o1.property1 = o2.property1 

ऑब्जेक्ट में सभी गुणों के लिए चीजें कर रहा हूं। ऑब्जेक्ट में सभी गुणों के माध्यम से लूप करने का सबसे प्रभावी तरीका क्या होगा और ऐसा करें? मैंने संपत्तियों के नल की जांच करने के लिए प्रॉपर्टीइन्फो का उपयोग करने वाले लोगों को देखा लेकिन ऐसा लगता है कि वे केवल PropertyInfo संग्रह से प्राप्त हो सकते हैं लेकिन गुणों के संचालन को लिंक नहीं करते हैं।

धन्यवाद।

static void CopyTo<T>(T from, T to) 
{ 
    foreach (PropertyInfo property in typeof(T).GetProperties()) 
    { 
     if (!property.CanRead || !property.CanWrite || (property.GetIndexParameters().Length > 0)) 
      continue; 

     object value = property.GetValue(to, null); 
     if (value != null) 
      property.SetValue(to, property.GetValue(from, null), null); 
    } 
} 

उत्तर

12

आप प्रतिबिंब के साथ ऐसा कर सकते हैं::

+0

धन्यवाद, जॉन, पूरी तरह से काम करता है! – NewDTinStackoverflow

2

अपने उदाहरण से आंकना मैं अपने कुछ इस तरह की तलाश में लगता है

public void CopyNonNullProperties(object source, object target) 
{ 
    // You could potentially relax this, e.g. making sure that the 
    // target was a subtype of the source. 
    if (source.GetType() != target.GetType()) 
    { 
     throw new ArgumentException("Objects must be of the same type"); 
    } 

    foreach (var prop in source.GetType() 
           .GetProperties(BindingFlags.Instance | 
               BindingFlags.Public) 
           .Where(p => !p.GetIndexParameters().Any()) 
           .Where(p => p.CanRead && p.CanWrite)) 
    { 
     var value = prop.GetValue(source, null); 
     if (value != null) 
     { 
      prop.SetValue(target, value, null); 
     } 
    } 
} 
+0

मैं दोनों वस्तुओं के एक ही प्रकार गारंटी नहीं है कि की एक जेनेरिक वर्जन होगा :) – khellang

+0

महान विचार @khellang :), मेरे उदाहरण –

+0

महान सामान बदल गया है! :) – khellang

2

आप इस कई बार, आप कर सकते थे उपयोग करने के लिए जा रहे हैं बेहतर प्रदर्शन के लिए एक संकलित अभिव्यक्ति का उपयोग करें:

public static class Mapper<T> 
{ 
    static Mapper() 
    { 
     var from = Expression.Parameter(typeof(T), "from"); 
     var to = Expression.Parameter(typeof(T), "to"); 

     var setExpressions = typeof(T) 
      .GetProperties() 
      .Where(property => property.CanRead && property.CanWrite && !property.GetIndexParameters().Any()) 
      .Select(property => 
      { 
       var getExpression = Expression.Call(from, property.GetGetMethod()); 
       var setExpression = Expression.Call(to, property.GetSetMethod(), getExpression); 
       var equalExpression = Expression.Equal(Expression.Convert(getExpression, typeof(object)), Expression.Constant(null)); 

       return Expression.IfThen(Expression.Not(equalExpression), setExpression); 
      }); 

     Map = Expression.Lambda<Action<T, T>>(Expression.Block(setExpressions), from, to).Compile(); 
    } 

    public static Action<T, T> Map { get; private set; } 
} 

और इसे इस तरह उपयोग करें:

Mapper<Entity>.Map(e1, e2); 
संबंधित मुद्दे