2013-07-30 5 views
5

CTO (CTO :)는 기본 클래스에서 하나의 함수를 작성할 수있는 방법을 생각해 냈습니다. 자식 클래스. 여기에 내가 무엇을 최대 온 것입니다 - 파일부모 클래스의 함수를 통해 하위 클래스 속성에 액세스

기본 클래스

class Assets 
{ 
    public Assets getPropertyVal(Assets asObj) 
    { 
     PropertyInfo[] propInfos = asObj.GetType().GetProperties(); 
     string strAttributeValue = "10"; 
     foreach (PropertyInfo propInfo in propInfos) 
     { 
      // Getting the value 
      var propValue = propInfo.GetValue(asObj, null); 

      // Setting the value 
      propInfo.SetValue(asObj, Convert.ChangeType(strAttributeValue, propInfo.PropertyType), null); 

     } 
     return asObj; 
    } 
} 

하위 클래스

class House : Assets 
{ 
    public int rooms{get; set;} 
} 

Program.cs

class Program 
{ 
    static void Main(string[] args) 
    { 
     House hsObj = new House(); 
     hsObj.rooms = 5; 

     Assets asObj = hsObj.getPropertyVal(hsObj); 
     // Returns asObj as JSON 
    } 
} 

이제 제대로 작동하지만 C#에서이 작업을 수행하는 더 좋은 방법이 있는지 궁금합니다.

우리는 하위 클래스에 어떤 속성이 있는지 알지 못하므로 런타임에 결정해야합니다. 반사를 사용하지 않고 자식 클래스의 속성 중 하나에 액세스 할 수있는 더 좋은 방법이 있다면 분명히, 나는 그냥 궁금 만들기 :

UPDATE. 중요한 점은 자식 클래스가 가질 수있는 속성이 무엇인지 알지 못한다는 것입니다.

업데이트 # 2 : 많은 엔티티가있는 제품으로 작업하고 있습니다. 이 엔티티는 다른 속성을가집니다. 한 곳에서 모든 속성에 액세스하고 작업 할 수 있기를 원합니다. 이 함수는 정확히 같습니다. 모든 데이터에 액세스 할 수있는 단일 장소입니다.

+1

예제에서 개체를 만들고 개체의 모든 속성을 가져온 다음 개체에서 동일한 속성을 설정합니다. 다음과 같이 보입니다 :'var propValue = asObj.rooms; asObj.rooms = (int) propValue;'. 정확히 무엇을 원하니? 하위 클래스의 모든 속성을 기본 클래스로 복사 하시겠습니까? –

+0

@VyacheslavVolkov, 리플렉션을 사용하지 않고 하위 클래스 속성에 액세스하는 더 좋은 방법이 있는지 궁금합니다. –

+0

나는 이것의 목적을 이해하지 못한다. 귀하의 예제에서 당신은'Console.WriteLine (hsObj.rooms); '로 자식 속성 이름을 하드 코딩하고 있습니다. 당신은'hsObj = (House) hsObj.getPropertyVal (hsObj);'줄을 제거 할 수 있습니다. 반사가 완전히 낭비됩니다. 당신이 성취하고자하는 것에 대한 더 나은 예를 생각해 낼 수 있습니까? – Dan

답변

5

먼저, Program.cs는 사용자가 원하는 것을 실제로 "수행"하지 않습니다. 프로그램을 통해 다음과 같이 할 수 있습니다.

Asset myAsset = new House(); 
myAsset.Rooms = 5; 

그러나 어쨌든 왜 그렇게하고 싶습니까? 자산은 집없는 경우 당신이 먼저 확인해야합니다, 그래서 그것은 예외가 발생합니다 : 그 시점에서

if (myAsset is House) 
    myAsset.Rooms = 5; 

, 당신은뿐만 아니라 단지 비록 집에 캐스팅 수 있습니다. 상속 대신 PropertyBag 또는 사전을 사용하려는 것 같습니다.

당신이 설명하는 것은 이것이라고 생각합니다. 옵션 1은 실제로 어떤 클래스에서 사용할 수있는 속성을 제한하지 않으므로이 경우 사용자의 특정 상황에서 실제로 작동하지 않는다고 생각합니다.

// Option 1 
Asset asset = new House(); 
asset.SetProperty("Rooms", 5); 
var rooms = asset.GetProperty<int>("Rooms"); 

// Option 2 
Asset asset = new House(); 
asset.SetProperty("Rooms", 5); 
asset.SetProperty("SomePropertyOnAsset", 10); 
asset.SetProperty("SomethingElse", 15); // Throws ArgumentException 

세 번 째 옵션은 자산 DynamicObject하는 것입니다 :

// Option 1, a Property Bag (Note: this replaces the properties on the classes) 
class Asset 
{ 
    Dictionary<string, object> myPropertyBag = new Dictionary<string, object>(); 

    public T GetProperty<T>(string property) 
    { 
     // This throws if the property doesn't exist 
     return (T)myPropertyBag[property]; 
    } 

    public void SetProperty<T>(string property, T value) 
    { 
     // This adds the property if it doesn't exist 
     myPropertyBag[property] = (object)value; 
    } 
} 

// Option 2, use a switch and override this function in derived classes 
class Asset 
{ 
    public int SomePropertyOnAsset { get; set; } 

    public virtual T GetProperty<T>(string property) 
    { 
     switch (property) 
     { 
      case "SomePropertyOnAsset": return this.SomePropertyOnAsset; 

      default: throw new ArgumentException("property"); 
     } 
    } 

    public virtual void SetProperty<T>(string property, T value) 
    { 
     switch (property) 
     { 
      case "SomePropertyOnAsset": this.SomePropertyOnAsset = (int)value; 

      default: throw new ArgumentException("property"); 
     } 
    } 
} 

class House : Asset 
{ 
    public int Rooms { get; set; } 

    public virtual T GetProperty<T>(string property) 
    { 
     switch (property) 
     { 
      case "Rooms": return this.Rooms; 

      default: return base.GetProperty<T>(property); 
     } 
    } 

    public virtual void SetProperty<T>(string property, T value) 
    { 
     switch (property) 
     { 
      case "Rooms": this.Rooms = (int)value; 
       break; 

      default: base.SetProperty<T>(property, value); 
       break; 
     } 
    } 
} 

그런 다음이 당신이 그들을 사용하는 방법입니다. http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.aspx

자산 기반 클래스를 크게 변경하거나 모든 항목을 터치하고 싶지 않거나 반영하고 싶지 않으면 리플렉션을 사용해야합니다.

+0

내 업데이트를 확인하십시오. –

+0

감사합니다 DynamicObject 클래스는 흥미로운 것 같습니다. –

1

루크 그레이 비트가 맞을 것 같습니다. 그냥 집에 던지기 만하면됩니다.

House myHouse = asObj as House; 
if (myHouse != null) 
{ 
    // do some fun house stuff 
} 

Yacht myYacht = asObj as Yacht; 
if (myYacht != null) 
{ 
    // put on monocle 
} 
+0

나를 위해 일했습니다. 감사! – Willy

관련 문제