2010-08-10 5 views
12

또 다른 객체에 속성 값, 우리가 일반적으로 다음과 같은 구문을 사용하여 달성 : CA와 CB는 같은 클래스의 수 있습니다복사 한 객체에서 다른 객체 속성 값을 복사하려면 C#

ca.pro1 = cb.pro2; 
ca.pro2 = cb.pro2; 

.

더 간단한 synatx 또는 유틸리티 방법가 있으면 동일한 효과를 얻을 수 있습니까?

감사합니다.

+0

이것은 당신이 찾고있는 무엇 : ([C#에서 복제 오브젝트] https://stackoverflow.com/questions/ 78536/cloning-objects-in-c) –

답변

3

아니요. MemberwiseClone()이 있지만 그 참조를 직접 복사하면 동일한 객체에 대한 참조를 얻을 수 있다는 것을 의미하므로 잘못된 것일 수 있습니다. ICloneable 인터페이스를 구현하고이를 깊은 복사본에 사용할 수 있습니다. ICloneable 인터페이스가 캐스팅해야하는 Object를 반환하기 때문에 내 자신의 Clone() 메서드를 만드는 것을 선호합니다.

+3

ICloneable에 신경 쓰지 않고 인터페이스가 호출자가 "복제본"의 의미를 나타낼 수 없기 때문에 제대로 구현할 수 없습니다. –

+0

사실상의 표준은 딥 클론이라고 생각합니다.하지만 더 나은 유형 안전성 등을 위해 자신의 복제 방법을 만드는 것에 대해서도 말했습니다. –

10

이것은 ASP.NET MVC의 모델간에 멤버를 복사하는 데 사용되는 함수입니다. 동일한 유형에서 작동하는 코드를 찾는 동안이 코드는 동일한 속성을 갖는 다른 유형을 지원합니다.

반사를 사용하지만 더 깨끗하게합니다. Convert.ChangeType에주의하십시오. 필요하지 않을 수도 있습니다. 당신은 변환하는 대신 유형에 대한 점검을 할 수 있습니다. 이 확장 방법이기 때문에

public static TConvert ConvertTo<TConvert>(this object entity) where TConvert : new() 
{ 
    var convertProperties = TypeDescriptor.GetProperties(typeof(TConvert)).Cast<PropertyDescriptor>(); 
    var entityProperties = TypeDescriptor.GetProperties(entity).Cast<PropertyDescriptor>(); 

    var convert = new TConvert(); 

    foreach (var entityProperty in entityProperties) 
    { 
     var property = entityProperty; 
     var convertProperty = convertProperties.FirstOrDefault(prop => prop.Name == property.Name); 
     if (convertProperty != null) 
     { 
      convertProperty.SetValue(convert, Convert.ChangeType(entityProperty.GetValue(entity), convertProperty.PropertyType)); 
     } 
    } 

    return convert; 
} 

는 사용법은 간단하다 :

var result = original.ConvertTo<SomeOtherType>(); 
+0

PropertyDescriptor.SetValue가 작동하지 않아 var convertProperties = typeof (TConvert) .GetProperties(); - PropertyDescriptor의 – MHolzmayr

+0

대신 PropertyInfo 목록을 제공합니다. Hindsight에서는 "작동하지 않았습니다"는 의미를 가지지 만 코드는 실행되었지만 bool 속성, b/c와 같은 값은 설정하지 않았습니다. 개인 설정자 (D ' 오!). – MHolzmayr

14
public static void CopyPropertiesTo<T, TU>(this T source, TU dest) 
{ 
    var sourceProps = typeof (T).GetProperties().Where(x => x.CanRead).ToList(); 
    var destProps = typeof(TU).GetProperties() 
      .Where(x => x.CanWrite) 
      .ToList(); 

    foreach (var sourceProp in sourceProps) 
    { 
     if (destProps.Any(x => x.Name == sourceProp.Name)) 
     { 
      var p = destProps.First(x => x.Name == sourceProp.Name); 
      if(p.CanWrite) { // check if the property can be set or no. 
       p.SetValue(dest, sourceProp.GetValue(source, null), null); 
      } 
     } 

    } 

} 
3

내가 필요한 사항으로 착각하지 않다 경우이 방법이 쉽게 둘 사이에 속성 값의 복사본을 달성하기 위해 기존 인스턴스 (심지어 같은 유형이 아님)은 Automapper을 사용합니다.

  1. 매핑 구성
  2. 를 만든 다음

만큼 당신이 동일한 유형과 같은 이름 지정 규칙에 속성을 지킬, 모든 일을해야 .MAP (soure, 대상)로 전화하십시오.

예 :

MapperConfiguration _configuration = new MapperConfiguration(cnf => 
      { 
       cnf.CreateMap<SourceType, TargetType>(); 
      }); 
var mapper = new Mapper(_configuration); 
maper.DefaultContext.Mapper.Map(source, target) 
1
public static TTarget Convert<TSource, TTarget>(TSource sourceItem) 
     { 
      if (null == sourceItem) 
      { 
       return default(TTarget); 
      } 

      var deserializeSettings = new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace, }; 

      var serializedObject = JsonConvert.SerializeObject(sourceItem, deserializeSettings); 

      return JsonConvert.DeserializeObject<TTarget>(serializedObject); 
     } 

사용 :

promosion = YourClass.Convert<Promosion, PromosionExtension>(existsPromosion); 
관련 문제