2008-12-23 35 views
6

Tôi biết tôi có thể có một thuộc tính nhưng đó là công việc nhiều hơn tôi muốn đi ... và không đủ chung.Làm cách nào để lấy tên của một tài sản từ một tài sản trong C# (2.0)

tôi muốn làm một cái gì đó giống như

class Whotsit 
{ 
    private string testProp = "thingy"; 

    public string TestProp 
    { 
     get { return testProp; } 
     set { testProp = value; } 
    } 

} 

... 

Whotsit whotsit = new Whotsit(); 
string value = GetName(whotsit.TestProp); //precise syntax up for grabs.. 

nơi tôi mong đợi giá trị tương đương với "TestProp"

nhưng tôi không thể cho cuộc đời của tôi tìm ra phương pháp phản ánh đúng để viết Phương thức GetName ...

EDIT: Tại sao tôi muốn làm điều này? Tôi có một lớp để lưu trữ các cài đặt được đọc từ bảng 'tên', 'giá trị'. Điều này được điền bởi một phương pháp tổng quát dựa trên sự phản chiếu. Tôi rất muốn viết ngược lại ...

/// <summary> 
/// Populates an object from a datatable where the rows have columns called NameField and ValueField. 
/// If the property with the 'name' exists, and is not read-only, it is populated from the 
/// valueField. Any other columns in the dataTable are ignored. If there is no property called 
/// nameField it is ignored. Any properties of the object not found in the data table retain their 
/// original values. 
/// </summary> 
/// <typeparam name="T">Type of the object to be populated.</typeparam> 
/// <param name="toBePopulated">The object to be populated</param> 
/// <param name="dataTable">'name, 'value' Data table to populate the object from.</param> 
/// <param name="nameField">Field name of the 'name' field'.</param> 
/// <param name="valueField">Field name of the 'value' field.</param> 
/// <param name="options">Setting to control conversions - e.g. nulls as empty strings.</param> 

public static void PopulateFromNameValueDataTable<T> 
     (T toBePopulated, System.Data.DataTable dataTable, string nameField, string valueField, PopulateOptions options) 
    { 
     Type type = typeof(T); 
     bool nullStringsAsEmptyString = options == PopulateOptions.NullStringsAsEmptyString; 

     foreach (DataRow dataRow in dataTable.Rows) 
     { 
      string name = dataRow[nameField].ToString(); 
      System.Reflection.PropertyInfo property = type.GetProperty(name); 
      object value = dataRow[valueField]; 

      if (property != null) 
      { 
       Type propertyType = property.PropertyType; 
       if (nullStringsAsEmptyString && (propertyType == typeof(String))) 
       { 
        value = TypeHelper.EmptyStringIfNull(value); 
       } 
       else 
       { 
        value = TypeHelper.DefaultIfNull(value, propertyType); 
       } 

       property.SetValue(toBePopulated, System.Convert.ChangeType(value, propertyType), null); 
      } 
     } 
    } 

THÊM EDIT: Tôi vừa mới viết mã, có một trường hợp Whotsit và tôi muốn lấy chuỗi văn bản của thuộc tính 'TestProp'. Nó có vẻ kỳ lạ mà tôi biết, tôi chỉ có thể sử dụng "TestProp" theo nghĩa đen - hoặc trong trường hợp lớp của tôi với hàm datatable, tôi sẽ ở trong vòng lặp foreach của PropertyInfos. Tôi chỉ tò mò ...

Mã gốc có các hằng số chuỗi, mà tôi thấy vụng về.

+0

Bạn có thể có một câu trả lời ở đây http://stackoverflow.com/a/1225702/661933 – nawfal

Trả lời

6

Không, không có gì để làm điều này. Biểu thức whotsit.TestProp sẽ đánh giá thuộc tính. Những gì bạn muốn là nhà điều hành "infoof" thần thoại:

// I wish... 
MemberInfo member = infoof(whotsit.TestProp); 

Vì vậy, bạn chỉ có thể sử dụng sự phản chiếu để lấy thuộc tính theo tên - không phải từ mã. (Hoặc có được tất cả các thuộc tính, tất nhiên nó vẫn không giúp bạn với mẫu của bạn mặc dù..)

Một thay thế là sử dụng một cây biểu thức:

Expression<Func<string>> =() => whotsit.TestProp; 

sau đó kiểm tra các cây biểu thức để có được bất động sản.

Nếu không điều nào trong số này hữu ích, có lẽ bạn có thể cho chúng tôi biết thêm về lý do bạn muốn chức năng này?

-1

GetProperties on the Type class sẽ cung cấp cho bạn danh sách thuộc tính trên loại đó.

Type t = whotsit.GetType(); 
PropertyInfo[] pis = t.GetProperties(); 
+0

sử dụng đúng, nhưng không nhiều cho những gì tôi muốn làm vì nó là chuỗi tên mà tôi đang theo sau ... – kpollock

0

Điều bạn đang cố gắng làm là không thể. Sử dụng phản ánh bạn có thể:

  • Nhận chi tiết về thuộc tính, trường hoặc phương pháp từ tên chuỗi của nó.
  • Nhận danh sách tất cả thuộc tính, trường hoặc phương pháp cho một loại nhất định.

Phương thức GetName của bạn, khi được gọi, được chuyển một chuỗi. GetMethod sẽ biết về chuỗi nhưng không giữ lại dữ liệu meta thuộc tính nguồn.

Không quan tâm, tại sao bạn lại cố gắng thực hiện việc này?

0

Tôi không nghĩ rằng nó có thể, cách duy nhất để làm điều này là để lặp qua các thuộc tính:

class TestClass 
{ 
    private string _field; 

    public string MyProperty 
    { 
     get { return _field; } 
    } 
} 
class Program 
{ 
    static void Main(string[] args) 
    { 
     TestClass test = new TestClass(); 
     PropertyInfo[] info = test.GetType().GetProperties(); 
     foreach(PropertyInfo i in info) 
      Console.WriteLine(i.Name); 
     Console.Read(); 
    } 
} 
+0

mà vẫn không cho tôi khả năng lấy tên của một tài sản từ một ví dụ của nó. – kpollock

3

Có thể (không phản ánh) nhưng chỉ với mới nhất C# 3.0

nhanh & rất rất bẩn

class Program 
{ 
    static void Main() 
    { 
     string propertyName = GetName(() => AppDomain.CurrentDomain); 
     Console.WriteLine(propertyName); // prints "CurrentDomain" 
     Console.ReadLine(); 
    } 

    public static string GetName(Expression<Func<object>> property) 
    { 
     return property.Body.ToString().Split('.').Last(); 
    } 
} 

cập nhật: Tôi vừa mới nhận ra rằng Jon Skeet (ai ngạc nhiên? :) đã đề cập đến khả năng này nhưng tôi sẽ giữ câu trả lời của tôi ở đây chỉ trong trường hợp ai đó quan tâm đến một số ví dụ để bắt đầu.

+0

Cũng cần .NET 3.5 (OP tiểu bang 2.0) –

+0

Tôi biết nhưng đó là câu hỏi chung chung tốt và một người nào đó với .NET 3.5 có thể quan tâm đến điều này. –

+0

Tôi đồng ý, không sử dụng nhiều cho tôi, nhưng có thể sử dụng cho những người khác tìm kiếm. – kpollock

0

Kpollack, bạn nói trong một cuộc bình luận trước đó:

đó vẫn sẽ không cho tôi khả năng để có được tên của một tài sản từ một thể hiện của nó.

Điều này khiến tôi tin rằng bạn bằng cách nào đó có tham chiếu đến thuộc tính. Làm thế nào bạn nhận được tài liệu tham khảo này? Loại của nó là gì? Bạn có thể cung cấp mẫu mã không? Nếu đó là một đối tượng PropertyInfo, bạn đã có những gì bạn cần; vì đây không phải là trường hợp, chúng tôi đang làm việc với một cái gì đó khác, và tôi sẽ rất quan tâm để xem những gì nó là bạn làm phải làm việc với.

P.S. Tha thứ cho tôi vì có vẻ ngượng ngùng: sớm thôi, tôi chưa có đủ cà phê, và tôi không có IDE trước mặt mình. : -/

+0

Tôi chỉ trong mã, có một thể hiện của Whotsit và tôi muốn nhận được chuỗi văn bản của thuộc tính 'TestProp'. Nó có vẻ kỳ lạ mà tôi biết, tôi chỉ có thể sử dụng "TestProp" theo nghĩa đen - hoặc trong trường hợp lớp của tôi với hàm datatable, tôi sẽ ở trong vòng lặp foreach của PropertyInfos. Tôi chỉ là tò mò thôi. – kpollock

0

FYI, tôi đã cố gắng sắp xếp nó để xem liệu tình cờ có chứa tên thuộc tính, nhưng không may mắn.

không làm việc mã bên dưới:

Whotsit w = new Whotsit(); 
XmlSerializer xs = new XmlSerializer(w.TestProp.GetType()); 
TextWriter sw = new StreamWriter(@"c:\TestProp.xml"); 
xs.Serialize(sw, w.TestProp); 
sw.Close(); 
Các vấn đề liên quan