2016-03-03 36 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); 
      } 
     } 
    } 
}