2013-07-30 15 views
5

Mein CTO (Chief Technical Officer) bat mich, einen Weg zu finden, wo er eine einzige Funktion in der Basisklasse schreiben und Zugriff auf alle Eigenschaften von die Kindklasse. Hier ist, was ich kam mit -Zugriff auf untergeordnete Klasseneigenschaften durch Funktion in der übergeordneten Klasse

Base Class

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; 
    } 
} 

Kinder Klasse

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

Program.cs Datei

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

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

Nun funktioniert das gut, aber ich habe mich nur gefragt, ob es in C# einen besseren Weg dafür gibt.

Beachten Sie, dass wir nicht wissen, welche Eigenschaften in der untergeordneten Klasse vorhanden sein werden, so dass dies zur Laufzeit bestimmt werden muss.

UPDATE: machen deutlich,, ich habe mich nur gefragt, ob es einen besseren Weg, um die untergeordneten Klasse Eigenschaften zuzugreifen, eine ohne Reflexion verwendet wird. Der wichtige Punkt ist, dass wir keine Ahnung haben, welche Eigenschaften eine Kindklasse haben kann.

UPDATE # 2: Ich arbeite mit einem Produkt, das viele Einheiten hat. Diese Entitäten haben unterschiedliche Eigenschaften. Ich möchte mit all diesen Eigenschaften an einem einzigen Ort zugreifen und arbeiten können. Diese Funktion ist genau das. Es ist dieser eine Ort, von dem aus ich auf alle Daten zugreifen kann.

+1

In Ihrem Beispiel erstellen Sie ein Objekt, rufen alle Eigenschaften des Objekts ab und legen dann dieselben Eigenschaften im Objekt fest. Es sieht so aus: 'var propValue = asObj.rooms; asObj.rooms = (int) propValue; '. Was genau willst du? Möchten Sie alle Eigenschaften einer untergeordneten Klasse in eine Basisklasse kopieren? –

+0

@VyacheslavVolkov, ich habe mich nur gefragt, ob es eine bessere Möglichkeit gibt, auf die Eigenschaften der untergeordneten Klasse zuzugreifen, ohne Reflektion zu verwenden. –

+0

Ich verstehe den Zweck nicht. In Ihrem Beispiel codieren Sie den Namen der untergeordneten Eigenschaft mit 'Console.WriteLine (hsObj.rooms);'. Sie können auch die Zeile "hsObj = (House) hsObj.getPropertyVal (hsObj);" ganz loswerden. Die Reflexion ist völlig verschwendet. Können Sie sich ein besseres Beispiel für das vorstellen, was Sie erreichen möchten? – Dan

Antwort

5

Zuerst "tut" Ihr Program.cs nicht wirklich, was Sie sagen, dass Sie wollen. Es klingt wie Sie ein Programm wollen, so dass Sie dies tun können:

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

Aber warum sollte man auch das sowieso tun wollen? Wenn Ihr Kapital nicht ein Haus ist, wird es eine Ausnahme auslösen, so müssen Sie das erste überprüfen:

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

An diesem Punkt könnte man genauso gut werfen es nur wenn auch in einem Haus. Es klingt, als ob Sie ein PropertyBag oder ein Dictionary anstelle von Vererbung verwenden möchten.

Ich denke, was Sie beschreiben, ist dies. Beachten Sie, dass Option 1 nicht wirklich einschränkt, welche Eigenschaften in welchen Klassen verwendet werden können. Ich nehme an, dass dies für Ihren speziellen Fall nicht wirklich funktioniert.

// 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; 
     } 
    } 
} 

Dann ist dies, wie Sie sie verwenden:

// 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 

Eine dritte Option ist ein Asset-Dynamic zu machen.

Wenn Sie Ihre Asset-Basisklasse nicht wesentlich ändern oder ändern möchten oder keine Entität berühren, müssen Sie wahrscheinlich eine Reflektion verwenden.

+0

Überprüfen Sie mein Update. –

+0

Danke die DynamicObject-Klasse scheint interessant. –

1

Luke Gravitt hat wahrscheinlich Recht. Vielleicht möchtest du es einfach in ein Haus werfen.

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

Arbeitete für mich. Vielen Dank! – Willy