Làm thế nào để có được một giá trị tài sản dựa trên tên


147

Có cách nào để có được giá trị của một tài sản của một đối tượng dựa trên tên của nó không?

Ví dụ: nếu tôi có:

public class Car : Vehicle
{
   public string Make { get; set; }
}

var car = new Car { Make="Ford" };

Tôi muốn viết một phương thức mà tôi có thể chuyển vào tên thuộc tính và nó sẽ trả về giá trị thuộc tính. I E:

public string GetPropertyValue(string propertyName)
{
   return the value of the property;
}

Câu trả lời:


310
return car.GetType().GetProperty(propertyName).GetValue(car, null);

17
Hãy nhớ rằng vì điều này sử dụng sự phản chiếu, nó chậm hơn nhiều. Có lẽ không phải là một vấn đề, nhưng tốt để nhận thức được.
Matt Greer

"Không thể chuyển đổi từ Chuỗi sang BindingFlags"
Christine

5
Có cách nào "nhanh hơn" @MattGreer không?
FizxMike

44

Bạn sẽ phải sử dụng sự phản chiếu

public object GetPropertyValue(object car, string propertyName)
{
   return car.GetType().GetProperties()
      .Single(pi => pi.Name == propertyName)
      .GetValue(car, null);
}

Nếu bạn muốn thực sự ưa thích, bạn có thể biến nó thành một phương thức mở rộng:

public static object GetPropertyValue(this object car, string propertyName)
{
   return car.GetType().GetProperties()
      .Single(pi => pi.Name == propertyName)
      .GetValue(car, null);
}

Và sau đó:

string makeValue = (string)car.GetPropertyValue("Make");

Bạn muốn có GetValue thay vì SetValue
Matt Greer

Tôi có thể làm điều này cho SetValue không? làm sao?
Piero Alberto

1
điều nhỏ - phương thức mở rộng có lẽ không cần phải có biếncar
KyleMit

Để xem cách Đặt giá trị thuộc tính, dựa trên chuỗi propertyName, hãy xem câu trả lời tại đây: Đặt giá trị của các thuộc tính thông qua sự phản chiếu
nwsmith

35

Bạn muốn suy ngẫm

Type t = typeof(Car);
PropertyInfo prop = t.GetProperty("Make");
if(null != prop)
return prop.GetValue(this, null);

7
+1 Đây là câu trả lời hay nhất khi bạn hiển thị tất cả các đối tượng trung gian
Matt Greer

1
Thay vì chuyển giá trị thuộc tính, tôi có thể chuyển chỉ mục và lấy tên và giá trị thuộc tính (để tôi có thể lặp qua tất cả các thuộc tính) không?
singhswat

@singhswat Bạn nên hỏi như một câu hỏi mới.
Chuck Savage

7

Mẫu đơn giản (không ghi mã cứng phản chiếu trong máy khách)

class Customer
{
    public string CustomerName { get; set; }
    public string Address { get; set; }
    // approach here
    public string GetPropertyValue(string propertyName)
    {
        try
        {
            return this.GetType().GetProperty(propertyName).GetValue(this, null) as string;
        }
        catch { return null; }
    }
}
//use sample
static void Main(string[] args)
    {
        var customer = new Customer { CustomerName = "Harvey Triana", Address = "Something..." };
        Console.WriteLine(customer.GetPropertyValue("CustomerName"));
    }

7

Ngoài ra, những người khác trả lời, Thật dễ dàng để có được giá trị thuộc tính của bất kỳ đối tượng nào bằng cách sử dụng phương thức Tiện ích mở rộng như:

public static class Helper
    {
        public static object GetPropertyValue(this object T, string PropName)
        {
            return T.GetType().GetProperty(PropName) == null ? null : T.GetType().GetProperty(PropName).GetValue(T, null);
        }

    }

Cách sử dụng là:

Car foo = new Car();
var balbal = foo.GetPropertyValue("Make");

7

Mở rộng câu trả lời của Adam Rackis - chúng ta có thể làm cho phương thức mở rộng chung chung đơn giản như thế này:

public static TResult GetPropertyValue<TResult>(this object t, string propertyName)
{
    object val = t.GetType().GetProperties().Single(pi => pi.Name == propertyName).GetValue(t, null);
    return (TResult)val;
}

Bạn có thể ném một số xử lý lỗi xung quanh đó nếu bạn muốn.


1

Để tránh sự phản chiếu, bạn có thể thiết lập một Từ điển với các tên thích hợp của mình làm các khóa và hàm trong phần giá trị từ điển trả về các giá trị tương ứng từ các thuộc tính mà bạn yêu cầu.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.