2013-05-19 3 views
1

PHP에서 배열을 클래스의 옵션으로 전달한 다음 해당 배열을 기본값을 보유하는 다른 배열로 병합하는 것이 일반적입니다.두 객체를 PHP의 array_merge와 비슷한 방법으로 병합하십시오.

이와 비슷한 것.

class MyObject 
{ 
    private static $defaults = array('value'=>10); 
    private $settings; 

    public function Something(array $settings = array()) 
    { 
      $this->settings = array_merge(static::defaults,$settings); 
    } 
} 

당신은 jQuery를 또는 merge 기능을 소개하는 다른 라이브러리를 사용하여 자바 스크립트에서 뭔가를 할 수 있습니다. 이 스크립트를 사용하면 두 개의 자바 스크립트 객체를 가져 와서 병합 할 수 있습니다. 하나는 기본값으로 사용하고 다른 하나는 기본값을 대체 할 수 있습니다.

이 패턴은 많은 수의 기본값을 구성 할 수 있지만 필요한 설정 만 할당 할 수 있기 때문에 매우 유용합니다.

어쨌든 C#에 이와 같은 작업을 수행합니까?

공용 속성에서 리플렉션을 사용하여이 작업을 수행하는 함수를 작성할 수는 있지만 이미 완료되었을 것으로 생각했습니다.

편집 :

이 질문은 스택에 전에 물었지만, PHP와 자바 스크립트로 무엇을 할 수 있는지와 같은 단순성을 제공하는 방법에 나와 있지되었습니다.

+1

가능한 중복 : http://stackoverflow.com/questions/1358877/what-is-the-best-way-to-merge-two-objects-during-runtime-using-c?rq=1 – cgTag

+0

C#은 정적으로 입력 된 언어이므로 사람들은 C#에서이 작업을 수행하지 않습니다. 문자열은 객체의 속성을 나타내는 데 사용되지 않습니다. 이게 뭘 원해? –

+0

새로운 개체에 대한 속성 그룹을 설정하는 쉬운 방법입니다. – cgTag

답변

0

정확하게 원했던 대답을 찾을 수 없었습니다. 그래서 저는 이것을하기위한 작은 방법을 썼습니다. 같은 시간에 두 개의 객체를 가져 와서 null 값이 할당되지 않은 필드/속성을 나타내는 것으로 가정하면 해당 필드/속성을 병합합니다.

다음은 사용 예입니다. 통신 클래스에 대한 옵션을 보유 할 클래스를 작성하고 통신 클래스에 기본값을 부여한 다음 사용자 설정으로 통신을 초기화하십시오.

예제 설정 클래스입니다.

public class ComSettings 
{ 
    public int? Port; 
    public string? Address; 
    public bool? KeepAlive; 
} 

생성자에서 이러한 설정을 사용하는 클래스 예입니다.

public class ComLibrary 
{ 
    private static ComSettings _defaults = new ComSettings { Port = 80, Address = "localhost" }; 

    protected ComSettings settings; 

    public ComLibrary(ComSettings pSettings) 
    { 
     this.settings = ObjectMerge<ComSettings>(_defaults, pSettings); 
    } 
} 

이렇게하면 다른 클래스가 ComSettings을 사용하지만 각각 다른 기본값을 가질 수 있습니다. 유일한 제한은 필드/속성이 null 할당을 지원해야한다는 것입니다.

여기 구현은 ObjectMerge입니다.

/// <summary> 
    /// Creates a new object that contains the properties of the two objects merged together. 
    /// </summary> 
    /// <typeparam name="T">The class type to merge.</typeparam> 
    /// <param name="pDefaults">Instance of the defaults object.</param> 
    /// <param name="pSettings">Instance of the settings object.</param> 
    /// <returns>A new instance of T with the merged results.</returns> 
    public static T ObjectMerge<T>(T pDefaults, T pSettings, bool pMergeFields = true, bool pMergeProperties = true) where T : class, new() 
    { 
     T target = new T(); 
     Type type = typeof(T); 
     List<MemberInfo> infos = new List<MemberInfo>(type.GetMembers()); 

     foreach (MemberInfo info in infos) 
     { 
      // Copy values from either defaults or settings 
      if (pMergeFields && info.MemberType == MemberTypes.Field) 
      { 
       FieldInfo field = (FieldInfo)info; 
       if (field.IsPublic) 
       { 
        object value = field.GetValue(pSettings); 
        value = (value == null) ? field.GetValue(pDefaults) : value; 
        field.SetValue(target, value); 
       } 
      } 

      // Copy values from either defaults or settings 
      if (pMergeProperties && info.MemberType == MemberTypes.Property) 
      { 
       PropertyInfo prop = (PropertyInfo)info; 
       if (prop.CanWrite && prop.CanRead) 
       { 
        object value = prop.GetValue(pSettings, null); 
        value = (value == null) ? prop.GetValue(pDefaults, null) : value; 
        prop.SetValue(target, value, null); 
       } 
      } 
     } 

     return target; 
    } 

그리고 여기에 간단한 단위 테스트가 있습니다.

/// <summary> 
///This is a test class for CoreUtilsTest and is intended 
///to contain all CoreUtilsTest Unit Tests 
///</summary> 
[TestClass()] 
public class CoreUtilsTest 
{ 
    /// <summary> 
    /// A class to perform testing on. 
    /// </summary> 
    public class MyClassA 
    { 
     public string Param1; 
     public string Param2; 
     public string Param3; 
    } 

    /// <summary> 
    /// A class to perform testing on. 
    /// </summary> 
    public class MyClassB 
    { 
     private string _param1; 

     public string Param1 
     { 
      get { return _param1; } 
      set { _param1 = value; } 
     } 
     private string _param2; 

     public string Param2 
     { 
      get { return _param2; } 
      set { _param2 = value; } 
     } 
     private string _param3; 

     public string Param3 
     { 
      get { return _param3; } 
      set { _param3 = value; } 
     } 
    } 

    /// <summary> 
    ///A test for SetProperties 
    ///</summary> 
    [TestMethod()] 
    public void Merging_Fields() 
    { 
     MyClassA defaults = new MyClassA { Param1 = "defaults" }; 
     MyClassA settings = new MyClassA { Param2 = "settings" }; 
     MyClassA results = CoreUtils.ObjectMerge<MyClassA>(defaults, settings); 

     Assert.AreEqual("defaults", results.Param1); 
     Assert.AreEqual("settings", results.Param2); 
     Assert.AreEqual(null, results.Param3); 
    } 

    [TestMethod()] 
    public void Merging_Properties() 
    { 
     MyClassB defaults = new MyClassB { Param1 = "defaults" }; 
     MyClassB settings = new MyClassB { Param2 = "settings" }; 
     MyClassB results = CoreUtils.ObjectMerge<MyClassB>(defaults, settings); 

     Assert.AreEqual("defaults", results.Param1); 
     Assert.AreEqual("settings", results.Param2); 
     Assert.AreEqual(null, results.Param3); 
    } 

} 
관련 문제