Nhận giá trị thuộc tính từ chuỗi bằng phản xạ trong C #


928

Tôi đang cố gắng thực hiện chuyển đổi Dữ liệu bằng ví dụ Reflection 1 trong mã của mình.

Các GetSourceValuechức năng có một công tắc so sánh các loại khác nhau, nhưng tôi muốn loại bỏ các loại và các đặc tính và có GetSourceValueđược giá trị của tài sản chỉ sử dụng một chuỗi duy nhất là tham số. Tôi muốn vượt qua một lớp và thuộc tính trong chuỗi và giải quyết giá trị của thuộc tính.

Điều này có thể không?

1 phiên bản Lưu trữ web của bài đăng blog gốc

Câu trả lời:


1793
 public static object GetPropValue(object src, string propName)
 {
     return src.GetType().GetProperty(propName).GetValue(src, null);
 }

Tất nhiên, bạn sẽ muốn thêm xác nhận và không có gì, nhưng đó là ý chính của nó.


8
Đẹp và đơn giản! Tôi muốn nói chung chung:public static T GetPropertyValue<T>(object obj, string propName) { return (T)obj.GetType().GetProperty(propName).GetValue(obj, null); }
Ohad Schneider

2
Tối ưu hóa có thể loại bỏ rủi ro của ngoại lệ null như thế này: " src.GetType().GetProperty(propName)?.GetValue(src, null);";).
shA.t

8
@ shA.t: Tôi nghĩ đó là một ý tưởng tồi. Làm thế nào để bạn phân biệt giữa một giá trị null của một tài sản hiện có hoặc không có tài sản nào cả? Tôi muốn biết ngay rằng tôi đã gửi một tên tài sản xấu. Đây không phải là mã sản xuất, nhưng một cải tiến tốt hơn sẽ là đưa ra một ngoại lệ cụ thể hơn (ví dụ: kiểm tra null GetPropertyvà ném PropertyNotFoundExceptionhoặc một cái gì đó nếu null.)
Ed S.

210

Còn những thứ như thế này thì sao:

public static Object GetPropValue(this Object obj, String name) {
    foreach (String part in name.Split('.')) {
        if (obj == null) { return null; }

        Type type = obj.GetType();
        PropertyInfo info = type.GetProperty(part);
        if (info == null) { return null; }

        obj = info.GetValue(obj, null);
    }
    return obj;
}

public static T GetPropValue<T>(this Object obj, String name) {
    Object retval = GetPropValue(obj, name);
    if (retval == null) { return default(T); }

    // throws InvalidCastException if types are incompatible
    return (T) retval;
}

Điều này sẽ cho phép bạn đi xuống các thuộc tính bằng một chuỗi duy nhất, như thế này:

DateTime now = DateTime.Now;
int min = GetPropValue<int>(now, "TimeOfDay.Minutes");
int hrs = now.GetPropValue<int>("TimeOfDay.Hours");

Bạn có thể sử dụng các phương thức này làm phương thức tĩnh hoặc phần mở rộng.


3
@FredJand rất vui khi bạn vấp phải nó! Nó luôn luôn ngạc nhiên khi những bài viết cũ bật lên. Đó là một chút mơ hồ vì vậy tôi đã thêm một chút văn bản để giải thích nó. Tôi cũng đã chuyển sang sử dụng chúng như các phương thức mở rộng và thêm một biểu mẫu tổng quát, vì vậy tôi đã thêm nó vào đây.
cưới

Tại sao người bảo vệ null trong foreach và không ở trên?
Santhos

4
@Santhos vì 'obj' được định nghĩa lại trong phần thân của vòng lặp foreach, nó được kiểm tra trong mỗi lần lặp.
cưới

Hữu ích, nhưng trong trường hợp cạnh có thể ẩn một trong các thuộc tính lồng nhau (sử dụng công cụ sửa đổi 'mới'), nó sẽ đưa ra một ngoại lệ để tìm các thuộc tính trùng lặp. Sẽ là gọn gàng hơn để theo dõi loại tài sản cuối cùng và sử dụng PropertyInfo.PropertyTypethay vì obj.GetType()trên các thuộc tính lồng nhau, giống như truy cập vào tài sản trên một thuộc tính lồng nhau.
Nullius

Bạn có thể sử dụng nameofbiểu thức kể từ C # 6 như thế này: nameof(TimeOfDay.Minutes)trên tham số tên khi gọi hàm để loại bỏ chuỗi ma thuật và thêm an toàn thời gian biên dịch cho các cuộc gọi này.
Riệp

74

Thêm vào bất kỳ Class:

public class Foo
{
    public object this[string propertyName]
    {
        get { return this.GetType().GetProperty(propertyName).GetValue(this, null); }
        set { this.GetType().GetProperty(propertyName).SetValue(this, value, null); }
    }

    public string Bar { get; set; }
}

Sau đó, bạn có thể sử dụng như:

Foo f = new Foo();
// Set
f["Bar"] = "asdf";
// Get
string s = (string)f["Bar"];

@EduardoCuomo: Có thể sử dụng sự phản chiếu với điều này để bạn không cần biết các thành viên của lớp có gì không?
Người đàn ông của chúng tôi ở Chuối

Có thể làm điều này nếu "Bar" là một đối tượng?
big_water

@big_water SetValueGetValuephương thức hoạt động với Object. Nếu bạn cần làm việc với một loại cụ thể, bạn nên bỏ kết quả GetValuevà bỏ giá trị để gán nó vớiSetValue
Eduardo Cuomo

Xin lỗi @OurManinBananas, tôi không thể hiểu câu hỏi của bạn. Bạn muốn làm gì?
Eduardo Cuomo

Tên của phương pháp loại này là gì ..?
Sahan Chinthaka

45

Gì về việc sử dụng CallByNamecủa Microsoft.VisualBasickhông gian tên ( Microsoft.VisualBasic.dll)? Nó sử dụng sự phản chiếu để có được các thuộc tính, trường và phương thức của các đối tượng bình thường, các đối tượng COM và thậm chí các đối tượng động.

using Microsoft.VisualBasic;
using Microsoft.VisualBasic.CompilerServices;

và sau đó

Versioned.CallByName(this, "method/function/prop name", CallType.Get).ToString();

5
Đề xuất thú vị, kiểm tra thêm đã chứng minh rằng nó có thể xử lý cả trường và thuộc tính, đối tượng COM và thậm chí nó có thể xử lý ràng buộc động chính xác !
IllidanS4 muốn Monica trở lại vào

Tôi đang gặp lỗi: Không tìm thấy thành viên công cộng 'MyPropertyName' trên loại 'MyType'.
vldmrrdjcc

30

Câu trả lời tuyệt vời của jheddings. Tôi muốn cải thiện nó cho phép tham chiếu các mảng hoặc bộ sưu tập các đối tượng tổng hợp, để propertyName có thể là property1.property2 [X] .property3:

    public static object GetPropertyValue(object srcobj, string propertyName)
    {
        if (srcobj == null)
            return null;

        object obj = srcobj;

        // Split property name to parts (propertyName could be hierarchical, like obj.subobj.subobj.property
        string[] propertyNameParts = propertyName.Split('.');

        foreach (string propertyNamePart in propertyNameParts)
        {
            if (obj == null)    return null;

            // propertyNamePart could contain reference to specific 
            // element (by index) inside a collection
            if (!propertyNamePart.Contains("["))
            {
                PropertyInfo pi = obj.GetType().GetProperty(propertyNamePart);
                if (pi == null) return null;
                obj = pi.GetValue(obj, null);
            }
            else
            {   // propertyNamePart is areference to specific element 
                // (by index) inside a collection
                // like AggregatedCollection[123]
                //   get collection name and element index
                int indexStart = propertyNamePart.IndexOf("[")+1;
                string collectionPropertyName = propertyNamePart.Substring(0, indexStart-1);
                int collectionElementIndex = Int32.Parse(propertyNamePart.Substring(indexStart, propertyNamePart.Length-indexStart-1));
                //   get collection object
                PropertyInfo pi = obj.GetType().GetProperty(collectionPropertyName);
                if (pi == null) return null;
                object unknownCollection = pi.GetValue(obj, null);
                //   try to process the collection as array
                if (unknownCollection.GetType().IsArray)
                {
                    object[] collectionAsArray = unknownCollection as object[];
                    obj = collectionAsArray[collectionElementIndex];
                }
                else
                {
                    //   try to process the collection as IList
                    System.Collections.IList collectionAsList = unknownCollection as System.Collections.IList;
                    if (collectionAsList != null)
                    {
                        obj = collectionAsList[collectionElementIndex];
                    }
                    else
                    {
                        // ??? Unsupported collection type
                    }
                }
            }
        }

        return obj;
    }

Điều gì về Danh sách Danh sách được MasterList truy cập [0] [1]?
Jesse Adam

as Array -> as object [] cũng dẫn đến ngoại lệ Nullreference. Những gì làm việc cho tôi (prop không phải là phương pháp hiệu quả nhất), là để kết nối unknownCollection thành IEnumerable và hơn là sử dụng ToArray () trên kết quả. fiddle
Jeroen Jonkman

14

Nếu tôi sử dụng mã từ Ed S. Tôi nhận được

'ReflectionExtensions.GetProperty (Loại, chuỗi)' không thể truy cập do mức độ bảo vệ của nó

Có vẻ như GetProperty()không có sẵn trong Xamarin.Forms. TargetFrameworkProfileProfile7 trong Thư viện lớp di động của tôi (.NET Framework 4.5, Windows 8, ASP.NET Core 1.0, Xamarin.Android, Xamarin.iOS, Xamarin.iOS Classic).

Bây giờ tôi tìm thấy một giải pháp làm việc:

using System.Linq;
using System.Reflection;

public static object GetPropValue(object source, string propertyName)
{
    var property = source.GetType().GetRuntimeProperties().FirstOrDefault(p => string.Equals(p.Name, propertyName, StringComparison.OrdinalIgnoreCase));
    return property?.GetValue(source);
}

Nguồn


4
Chỉ là một cải tiến nhỏ có thể. Thay thế IF và trả lại tiếp theo bằng: trả lại tài sản? .GetValue (nguồn);
Tomino

11

Về các cuộc thảo luận về các thuộc tính lồng nhau, bạn có thể tránh tất cả các công cụ phản chiếu nếu bạn sử dụng DataBinder.Eval Method (Object, String)như dưới đây:

var value = DataBinder.Eval(DateTime.Now, "TimeOfDay.Hours");

Tất nhiên, bạn sẽ cần thêm một tham chiếu đến System.Webhội đồng, nhưng điều này có lẽ không phải là vấn đề lớn.


8

Phương thức gọi đã thay đổi trong .NET Standard (kể từ 1.6). Ngoài ra, chúng ta có thể sử dụng toán tử điều kiện null của C # 6.

using System.Reflection; 
public static object GetPropValue(object src, string propName)
{
    return src.GetType().GetRuntimeProperty(propName)?.GetValue(src);
}

1
lên để sử dụng? operator
blfuentes

4

Sử dụng PropertyInfo của không gian tên System.Reflection . Reflection biên dịch tốt chỉ cho dù chúng ta cố gắng truy cập vào tài sản nào. Lỗi sẽ xuất hiện trong thời gian chạy.

    public static object GetObjProperty(object obj, string property)
    {
        Type t = obj.GetType();
        PropertyInfo p = t.GetProperty("Location");
        Point location = (Point)p.GetValue(obj, null);
        return location;
    }

Nó hoạt động tốt để có được thuộc tính Location của một đối tượng

Label1.Text = GetObjProperty(button1, "Location").ToString();

Chúng tôi sẽ nhận được Vị trí: {X = 71, Y = 27} Chúng tôi cũng có thể trả lại vị trí.X hoặc vị trí.Y trên cùng một cách.


4
public static List<KeyValuePair<string, string>> GetProperties(object item) //where T : class
    {
        var result = new List<KeyValuePair<string, string>>();
        if (item != null)
        {
            var type = item.GetType();
            var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (var pi in properties)
            {
                var selfValue = type.GetProperty(pi.Name).GetValue(item, null);
                if (selfValue != null)
                {
                    result.Add(new KeyValuePair<string, string>(pi.Name, selfValue.ToString()));
                }
                else
                {
                    result.Add(new KeyValuePair<string, string>(pi.Name, null));
                }
            }
        }
        return result;
    }

Đây là một cách để có được tất cả các thuộc tính với các giá trị của chúng trong Danh sách.


Tại sao làm điều này: type.GetProperty(pi.Name)khi đó là == cho biến pi?
weston

Nếu bạn đang sử dụng c # 6.0, hãy loại bỏ ifvà làm selfValue?.ToString()Nếu không hãy loại bỏ ifvà sử dụngselfValue==null?null:selfValue.ToString()
weston

Ngoài ra một danh sách List<KeyValuePair<là số lẻ, sử dụng từ điểnDictionary<string, string>
weston

3

Đoạn mã sau đây là một phương thức đệ quy để hiển thị toàn bộ hệ thống phân cấp của tất cả các Tên và giá trị thuộc tính có trong thể hiện của một đối tượng. Phương pháp này sử dụng một phiên bản đơn giản của GetPropertyValue()câu trả lời của AlexD ở trên trong chuỗi này. Nhờ chủ đề thảo luận này, tôi đã có thể tìm ra cách để làm điều này!

Ví dụ, tôi sử dụng phương thức này để hiển thị một vụ nổ hoặc kết xuất tất cả các thuộc tính trong một WebServicephản hồi bằng cách gọi phương thức như sau:

PropertyValues_byRecursion("Response", response, false);

public static object GetPropertyValue(object srcObj, string propertyName)
{
  if (srcObj == null) 
  {
    return null; 
  }
  PropertyInfo pi = srcObj.GetType().GetProperty(propertyName.Replace("[]", ""));
  if (pi == null)
  {
    return null;
  }
  return pi.GetValue(srcObj);
}

public static void PropertyValues_byRecursion(string parentPath, object parentObj, bool showNullValues)
{
  /// Processes all of the objects contained in the parent object.
  ///   If an object has a Property Value, then the value is written to the Console
  ///   Else if the object is a container, then this method is called recursively
  ///       using the current path and current object as parameters

  // Note:  If you do not want to see null values, set showNullValues = false

  foreach (PropertyInfo pi in parentObj.GetType().GetTypeInfo().GetProperties())
  {
    // Build the current object property's namespace path.  
    // Recursion extends this to be the property's full namespace path.
    string currentPath = parentPath + "." + pi.Name;

    // Get the selected property's value as an object
    object myPropertyValue = GetPropertyValue(parentObj, pi.Name);
    if (myPropertyValue == null)
    {
      // Instance of Property does not exist
      if (showNullValues)
      {
        Console.WriteLine(currentPath + " = null");
        // Note: If you are replacing these Console.Write... methods callback methods,
        //       consider passing DBNull.Value instead of null in any method object parameters.
      }
    }
    else if (myPropertyValue.GetType().IsArray)
    {
      // myPropertyValue is an object instance of an Array of business objects.
      // Initialize an array index variable so we can show NamespacePath[idx] in the results.
      int idx = 0;
      foreach (object business in (Array)myPropertyValue)
      {
        if (business == null)
        {
          // Instance of Property does not exist
          // Not sure if this is possible in this context.
          if (showNullValues)
          {
            Console.WriteLine(currentPath  + "[" + idx.ToString() + "]" + " = null");
          }
        }
        else if (business.GetType().IsArray)
        {
          // myPropertyValue[idx] is another Array!
          // Let recursion process it.
          PropertyValues_byRecursion(currentPath + "[" + idx.ToString() + "]", business, showNullValues);
        }
        else if (business.GetType().IsSealed)
        {
          // Display the Full Property Path and its Value
          Console.WriteLine(currentPath + "[" + idx.ToString() + "] = " + business.ToString());
        }
        else
        {
          // Unsealed Type Properties can contain child objects.
          // Recurse into my property value object to process its properties and child objects.
          PropertyValues_byRecursion(currentPath + "[" + idx.ToString() + "]", business, showNullValues);
        }
        idx++;
      }
    }
    else if (myPropertyValue.GetType().IsSealed)
    {
      // myPropertyValue is a simple value
      Console.WriteLine(currentPath + " = " + myPropertyValue.ToString());
    }
    else
    {
      // Unsealed Type Properties can contain child objects.
      // Recurse into my property value object to process its properties and child objects.
      PropertyValues_byRecursion(currentPath, myPropertyValue, showNullValues);
    }
  }
}

3
public static TValue GetFieldValue<TValue>(this object instance, string name)
{
    var type = instance.GetType(); 
    var field = type.GetFields(BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance).FirstOrDefault(e => typeof(TValue).IsAssignableFrom(e.FieldType) && e.Name == name);
    return (TValue)field?.GetValue(instance);
}

public static TValue GetPropertyValue<TValue>(this object instance, string name)
{
    var type = instance.GetType();
    var field = type.GetProperties(BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance).FirstOrDefault(e => typeof(TValue).IsAssignableFrom(e.PropertyType) && e.Name == name);
    return (TValue)field?.GetValue(instance);
}

3
public class YourClass
{
    //Add below line in your class
    public object this[string propertyName] => GetType().GetProperty(propertyName)?.GetValue(this, null);
    public string SampleProperty { get; set; }
}

//And you can get value of any property like this.
var value = YourClass["SampleProperty"];

3

Phương pháp dưới đây hoạt động hoàn hảo đối với tôi:

class MyClass {
    public string prop1 { set; get; }

    public object this[string propertyName]
    {
        get { return this.GetType().GetProperty(propertyName).GetValue(this, null); }
        set { this.GetType().GetProperty(propertyName).SetValue(this, value, null); }
    }
}

Để có được giá trị tài sản:

MyClass t1 = new MyClass();
...
string value = t1["prop1"].ToString();

Để đặt giá trị thuộc tính:

t1["prop1"] = value;

2
Dim NewHandle As YourType = CType(Microsoft.VisualBasic.CallByName(ObjectThatContainsYourVariable, "YourVariableName", CallType), YourType)

2

Đây là một cách khác để tìm một thuộc tính lồng nhau không yêu cầu chuỗi cho bạn biết đường dẫn lồng. Tín dụng cho Ed S. cho phương pháp tài sản duy nhất.

    public static T FindNestedPropertyValue<T, N>(N model, string propName) {
        T retVal = default(T);
        bool found = false;

        PropertyInfo[] properties = typeof(N).GetProperties();

        foreach (PropertyInfo property in properties) {
            var currentProperty = property.GetValue(model, null);

            if (!found) {
                try {
                    retVal = GetPropValue<T>(currentProperty, propName);
                    found = true;
                } catch { }
            }
        }

        if (!found) {
            throw new Exception("Unable to find property: " + propName);
        }

        return retVal;
    }

        public static T GetPropValue<T>(object srcObject, string propName) {
        return (T)srcObject.GetType().GetProperty(propName).GetValue(srcObject, null);
    }

Có thể tốt hơn để kiểm tra nếu Type.GetPropertytrả về null thay vì gọi GetValueNullReferenceExceptionbị ném trong một vòng lặp.
Groo

2

Bạn không bao giờ đề cập đến đối tượng nào bạn đang kiểm tra và vì bạn đang từ chối những đối tượng tham chiếu đến một đối tượng nhất định, tôi sẽ cho rằng bạn có nghĩa là một đối tượng tĩnh.

using System.Reflection;
public object GetPropValue(string prop)
{
    int splitPoint = prop.LastIndexOf('.');
    Type type = Assembly.GetEntryAssembly().GetType(prop.Substring(0, splitPoint));
    object obj = null;
    return type.GetProperty(prop.Substring(splitPoint + 1)).GetValue(obj, null);
}

Lưu ý rằng tôi đã đánh dấu đối tượng đang được kiểm tra với biến cục bộ obj . nullcó nghĩa là tĩnh, nếu không thì đặt nó thành những gì bạn muốn. Cũng lưu ý rằng đây GetEntryAssembly()là một trong một vài phương thức có sẵn để có được "lắp ráp", bạn có thể muốn chơi xung quanh nó nếu bạn gặp khó khăn khi tải loại.


2

Hãy xem thư viện Heleonix.Reflection . Bạn có thể nhận / đặt / gọi thành viên theo đường dẫn hoặc tạo getter / setter (lambda được biên dịch thành đại biểu) nhanh hơn phản xạ. Ví dụ:

var success = Reflector.Get(DateTime.Now, null, "Date.Year", out int value);

Hoặc tạo một getter một lần và bộ đệm để sử dụng lại (cái này hiệu quả hơn nhưng có thể ném NullReferenceException nếu một thành viên trung gian là null):

var getter = Reflector.CreateGetter<DateTime, int>("Date.Year", typeof(DateTime));
getter(DateTime.Now);

Hoặc nếu bạn muốn tạo một List<Action<object, object>>getters khác nhau, chỉ cần chỉ định các loại cơ sở cho các đại biểu được biên dịch (chuyển đổi loại sẽ được thêm vào lambdas đã biên dịch):

var getter = Reflector.CreateGetter<object, object>("Date.Year", typeof(DateTime));
getter(DateTime.Now);

1
không bao giờ sử dụng libs của bên thứ 3, nếu bạn có thể triển khai nó theo mã của riêng mình trong thời gian hợp lý trong 5-10 dòng.
Artem G

1

cách ngắn hơn ....

var a = new Test { Id = 1 , Name = "A" , date = DateTime.Now};
var b = new Test { Id = 1 , Name = "AXXX", date = DateTime.Now };

var compare = string.Join("",a.GetType().GetProperties().Select(x => x.GetValue(a)).ToArray())==
              string.Join("",b.GetType().GetProperties().Select(x => x.GetValue(b)).ToArray());

1

jheddingsAlexD đều viết câu trả lời xuất sắc về cách giải quyết chuỗi thuộc tính. Tôi muốn ném tôi vào hỗn hợp, vì tôi đã viết một thư viện chuyên dụng chính xác cho mục đích đó.

Lớp chính của Pather.CSharpResolver. Theo mặc định, nó có thể giải quyết các thuộc tính, mảng và mục từ điển.

Vì vậy, ví dụ, nếu bạn có một đối tượng như thế này

var o = new { Property1 = new { Property2 = "value" } };

và muốn có được Property2, bạn có thể làm như thế này:

IResolver resolver = new Resolver();
var path = "Property1.Property2";
object result = r.Resolve(o, path); 
//=> "value"

Đây là ví dụ cơ bản nhất về các đường dẫn mà nó có thể giải quyết. Nếu bạn muốn xem những gì nó có thể, hoặc làm thế nào bạn có thể mở rộng nó, chỉ cần đi đến trang Github của nó .


0

Đây là giải pháp của tôi. Nó cũng hoạt động với các đối tượng COM và cho phép truy cập các mục bộ sưu tập / mảng từ các đối tượng COM.

public static object GetPropValue(this object obj, string name)
{
    foreach (string part in name.Split('.'))
    {
        if (obj == null) { return null; }

        Type type = obj.GetType();
        if (type.Name == "__ComObject")
        {
            if (part.Contains('['))
            {
                string partWithoundIndex = part;
                int index = ParseIndexFromPropertyName(ref partWithoundIndex);
                obj = Versioned.CallByName(obj, partWithoundIndex, CallType.Get, index);
            }
            else
            {
                obj = Versioned.CallByName(obj, part, CallType.Get);
            }
        }
        else
        {
            PropertyInfo info = type.GetProperty(part);
            if (info == null) { return null; }
            obj = info.GetValue(obj, null);
        }
    }
    return obj;
}

private static int ParseIndexFromPropertyName(ref string name)
{
    int index = -1;
    int s = name.IndexOf('[') + 1;
    int e = name.IndexOf(']');
    if (e < s)
    {
        throw new ArgumentException();
    }
    string tmp = name.Substring(s, e - s);
    index = Convert.ToInt32(tmp);
    name = name.Substring(0, s - 1);
    return index;
}

0

Đây là những gì tôi nhận được dựa trên các câu trả lời khác. Một chút quá mức về việc quá cụ thể với việc xử lý lỗi.

public static T GetPropertyValue<T>(object sourceInstance, string targetPropertyName, bool throwExceptionIfNotExists = false)
{
    string errorMsg = null;

    try
    {
        if (sourceInstance == null || string.IsNullOrWhiteSpace(targetPropertyName))
        {
            errorMsg = $"Source object is null or property name is null or whitespace. '{targetPropertyName}'";
            Log.Warn(errorMsg);

            if (throwExceptionIfNotExists)
                throw new ArgumentException(errorMsg);
            else
                return default(T);
        }

        Type returnType = typeof(T);
        Type sourceType = sourceInstance.GetType();

        PropertyInfo propertyInfo = sourceType.GetProperty(targetPropertyName, returnType);
        if (propertyInfo == null)
        {
            errorMsg = $"Property name '{targetPropertyName}' of type '{returnType}' not found for source object of type '{sourceType}'";
            Log.Warn(errorMsg);

            if (throwExceptionIfNotExists)
                throw new ArgumentException(errorMsg);
            else
                return default(T);
        }

        return (T)propertyInfo.GetValue(sourceInstance, null);
    }
    catch(Exception ex)
    {
        errorMsg = $"Problem getting property name '{targetPropertyName}' from source instance.";
        Log.Error(errorMsg, ex);

        if (throwExceptionIfNotExists)
            throw;
    }

    return default(T);
}
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.