วิธีรับค่าคุณสมบัติตามชื่อ


147

มีวิธีการรับค่าคุณสมบัติของวัตถุตามชื่อหรือไม่

เช่นถ้าฉันมี:

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

และ

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

ฉันต้องการเขียนวิธีการที่ฉันสามารถส่งผ่านในชื่อคุณสมบัติและมันจะส่งกลับค่าคุณสมบัติ เช่น:

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

คำตอบ:


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

17
โปรดทราบว่าเนื่องจากสิ่งนี้ใช้การสะท้อนจึงช้ากว่ามาก อาจไม่ใช่ปัญหา แต่ก็ดีที่ต้องระวัง
Matt Greer

"ไม่สามารถแปลงจากสตริงเป็น BindingFlags"
Christine

5
@MattGreer มีวิธี "เร็วกว่า" หรือไม่
FizxMike

44

คุณต้องใช้การไตร่ตรอง

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

หากคุณต้องการที่จะแฟนซีจริงๆคุณสามารถทำให้มันเป็นวิธีการขยาย:

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

แล้ว:

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

คุณต้องการ GetValue แทน SetValue
Matt Greer

ฉันสามารถทำสิ่งนี้กับ SetValue ได้หรือไม่ อย่างไร
Piero Alberto

1
เมธอดส่วนขยายเล็กน้อย - อาจไม่จำเป็นต้องมีตัวแปรชื่อcar
KyleMit

เพื่อดูวิธีการตั้งค่าคุณสมบัติขึ้นอยู่กับสตริง propertyName ดูคำตอบที่นี่: การตั้งค่าของคุณสมบัติผ่านการสะท้อน
nwsmith

35

คุณต้องการ Reflection

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

7
+1 นี่คือคำตอบที่ดีที่สุดเมื่อคุณแสดงวัตถุกลางทั้งหมด
Matt Greer

1
แทนที่จะส่งค่าคุณสมบัติฉันสามารถส่งดัชนีและรับชื่อคุณสมบัติและค่า (เพื่อให้สามารถวนลูปผ่านคุณสมบัติทั้งหมด) ได้หรือไม่
singhswat

@singhswat คุณควรถามว่าเป็นคำถามใหม่
Chuck Savage

7

ตัวอย่างง่าย ๆ (โดยไม่เขียนโค้ดสะท้อนความเห็นอย่างหนักในไคลเอนต์)

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

นอกจากนี้คนอื่น ๆ ตอบมันง่ายที่จะได้รับมูลค่าทรัพย์สินของวัตถุใด ๆโดยใช้วิธีการขยายเช่น:

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

    }

การใช้งานคือ:

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

7

ขยายคำตอบของ Adam Rackis - เราสามารถสร้างวิธีการขยายทั่วไปแบบนี้:

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

คุณสามารถจัดการกับข้อผิดพลาดบางอย่างเช่นกันหากคุณต้องการ


1

เพื่อหลีกเลี่ยงการสะท้อนคุณสามารถตั้งค่าพจนานุกรมด้วยชื่อที่เหมาะสมของคุณเป็นคีย์และฟังก์ชั่นในส่วนค่าพจนานุกรมที่ส่งคืนค่าที่สอดคล้องกันจากคุณสมบัติที่คุณร้องขอ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.