2016-03-03 32 views
1

的對象類...獲取使用屬性的字符串不反映

class Room 
    { 
     public string Value1 { get; set; } 
     public string Value2 { get; set; } 
     public string Value3 { get; set; } 

     public Room() 
     { 
      this.Value1 = "one"; 
      this.Value2 = "two"; 
      this.Value3 = "three"; 

     } 

    } 

    class Building 

    { 
     public Room Room-Bob { get; set; } 
     public Room Room-Steve{ get; set; } 

     public Building() 
     { 
      this.Room-Bob = new Room(); 
      this.Room-Steve = new Room(); 
     } 

    } 

    class Street 

    { 
     public Building Building-Black{ get; set; } 
     public Building Building-Blue { get; set; } 
     public Building Building-Yellow { get; set; } 
     public Building Building-White { get; set; } 

     public Street() 
     { 
      this.Building-Black = new Building(); 
      this.Building-Blue = new Building(); 
      this.Building-Yellow = new Building(); 
      this.Building-White = new Building(); 

     } 

    } 

我現在使用的是什麼來獲取值...

class go 
{ 
    public void go() 
    { 
     string SelectedValue = ""; 
     Street s = new Street(); 
     string PathToProperty = "s.Building1.Room1.value1"; 

     if(PathToProperty == "s.Building1.Room1.value1") { SelectedValue = s.Building1.Room1.Value1; } 

     if (PathToProperty == "s.Building1.Room1.value2") { SelectedValue = s.Building1.Room1.Value2; } 


    } 

} 

我怎麼想獲取值...或者類似的東西

string PathToProperty = "s.Building1.Room1.value1";  
SelectedValue = PathToProperty; 

我也想這樣設置屬性...

string PathToProperty =「s.Building1.Room1.value1」;
SelectedValue = PathToProperty;

原因是我通過將一堆組合框中的文本串在一起來製作PathToProperty。最終,我想避免隨着組合框內的選項的增加,不得不添加到我的IF語句列表中。

我一直在反思,但想避免這種情況,我讀了一個地方,你可以用接口做到這一點(使用它們來暴露屬性),但我不知道如何。

如果反射是最好的選擇,有人可以告訴我兩種方法來獲得財產,另一種設置它?

+1

反思是明確設計做你想做什麼工具。你爲什麼認爲這是一個不好的選擇? – Luaan

+0

A-我不能讓它正常工作B-每個人都說如果反射是最好的方式,那麼我應該避免它,那麼我將如何獲得和設置屬性 – user3755946

+0

你應該考慮使用數組或列表。它們可以被編入索引,似乎更貼近你想要實現的內容。或者可能是一本詞典。 –

回答

3

我建議你採取不同的方法。國際海事組織的反思並不適合這種情況。

開始本,然後從它建立 - 重新設計/重構等部位爲好,當然:

class Room 
{ 
    // same as yours 
} 

class Building 
{ 
    public List<Room> Rooms { get; set; } 

    public Building() 
    { 
     Rooms = new List<Room>(); 
     Rooms.Add(new Room()); 
     Rooms.Add(new Room()); 
     // get "room #x" -> var room = objBuilding.Rooms[x]; 
     // get "room #x in building #i" -> var room = objStreet.Buildings[i].Rooms[x]; 
    } 
} 

class Street 
{ 
    public List<Building> Buildings { get; set; } 

    public Street() 
    { 
     Buildings = new List<Building>(); 
     Buildings.Add(new Building()); 
     Buildings.Add(new Building()); 
     Buildings.Add(new Building()); 
     Buildings.Add(new Building()); 
     // get "building #i" -> var building = objStreet.Buildings[i]; 
    } 
} 
+0

感謝您的答案不知道如何使用它,但我需要能夠訪問它使用建築物名稱不是一個數字。 – user3755946

+0

這就是爲什麼我說:重新設計/重構其他部分。您可以拆分字符串,提取數字然後使用它們。請記住Array/List索引是從零開始的,而您的數字可能從1開始。 –

+0

var pathParts = PathToProperty.Split('。「); //開始 –

1

也許你應該嘗試使用使用延伸關鍵字這樣你可以一個超類在一個對象中使用來自多個類的方法和構造函數。例如,如果您的「超級建築」和「街道」和「房間」作爲子類,並在其中構建適當的構造函數,您可以在「走出去」類中調用「構建」對象,並擁有全部「走」的「街道」和「房間」的方法和數據點可用。

編輯:我沒有看到c#的標籤我使用的是Java,但繼承原則適用於各種語言,因此請使用您的語言的等效語言。

1

我建議你以下解決方案:

using System; 
using System.Collections.Generic; 
using System.Dynamic; 
using System.Linq; 
using System.Linq.Expressions; 
using System.Reflection; 
using System.Runtime.CompilerServices; 
using System.Text; 
using System.Threading.Tasks; 
using Microsoft.CSharp.RuntimeBinder; 
using Binder = Microsoft.CSharp.RuntimeBinder.Binder; 

namespace ConsoleApplication2 
{ 
    class Program 
    { 
     class Room 
     { 
      public string Value1 { get; set; } 
      public string Value2 { get; set; } 
      public string Value3 { get; set; } 

      public Room() 
      { 
       this.Value1 = "one"; 
       this.Value2 = "two"; 
       this.Value3 = "three"; 

      } 

     } 

     class Building{ 
      public Room Room1 { get; set; } 
      public Room Room2 { get; set; } 

      public Building() 
      { 
       this.Room1 = new Room(); 
       this.Room2 = new Room(); 
      } 
     } 

     class Street{ 
      public Building Building1 { get; set; } 
      public Building Building2 { get; set; } 
      public Building Building3 { get; set; } 
      public Building Building4 { get; set; } 

      public Street() 
      { 
       this.Building1 = new Building(); 
       this.Building2 = new Building(); 
       this.Building3 = new Building(); 
       this.Building4 = new Building(); 

      } 

     } 

     public static void Main(string[] args) 
     { 
      string SelectedValue = ""; 
      Street s = new Street(); 

      string buildingPropertyAsString = "Building3"; 

      var splittedPath = "s.Building1.Room1.Value1".Split('.'); 

      var neededValue = 
       ((s.GetProperty(splittedPath[1]) as Building).GetProperty(splittedPath[2]) as Room).GetProperty(
        splittedPath[3]) as string; 


     } 
    } 

    public static class TypeExtentions 
    { 
     public static object GetProperty(this object o, string member) 
     { 
      if (o == null) throw new ArgumentNullException("o"); 
      if (member == null) throw new ArgumentNullException("member"); 
      Type scope = o.GetType(); 
      IDynamicMetaObjectProvider provider = o as IDynamicMetaObjectProvider; 
      if (provider != null) 
      { 
       ParameterExpression param = Expression.Parameter(typeof(object)); 
       DynamicMetaObject mobj = provider.GetMetaObject(param); 
       GetMemberBinder binder = (GetMemberBinder)Microsoft.CSharp.RuntimeBinder.Binder.GetMember(0, member, scope, new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(0, null) }); 
       DynamicMetaObject ret = mobj.BindGetMember(binder); 
       BlockExpression final = Expression.Block(
        Expression.Label(CallSiteBinder.UpdateLabel), 
        ret.Expression 
        ); 
       LambdaExpression lambda = Expression.Lambda(final, param); 
       Delegate del = lambda.Compile(); 
       return del.DynamicInvoke(o); 
      } 
      else { 
       return o.GetType().GetProperty(member, BindingFlags.Public | BindingFlags.Instance).GetValue(o, null); 
      } 
     } 
    } 
}