C# 泛型类型类无法获取属性值

Kho*_*yen 4 c# generics reflection field object

使用 C# 反射获取和设置通用对象内通用字段的值。但我找不到任何方法来获取这些字段的属性值。下面的代码示例:

public class Foo<T>
{
   public bool IsUpdated { get; set; } 
}

public abstract class ValueObjec<T>
{
   public string InnerValue { get; set; } 
}

public class ItemList: ValueObject<ItemList>
{
   public Foo<string> FirstName;

   public Foo<string> LastName;
}
Run Code Online (Sandbox Code Playgroud)

获取行 (*) 处的“空”项时出现问题。

itemField.GetType() 始终返回System.Reflection.RtFieldInfo类型,但不返回Foo类型。

我已经尝试使用 itemField.FieldType.GetProperty("IsUpdated"),它在返回正确的属性时有效。但抛出错误“对象与目标类型不匹配”。每当调用 GetValue() 方法 itemField.FieldType.GetProperty("IsUpdated").GetValue(itemField, null)

如果得到任何人的帮助,我们将不胜感激!

var itemList = new ItemList();
foreach (var itemField in itemList.GetType().GetFields())
{
    var isUpdated = "false";
    var isUpdatedProp = itemField.GetType().GetProperty("IsUpdated"); // (*) return null from here
    if (isUpdatedProp != null)
    {
        isUpdated = isUpdatedProp.GetValue(itemField, null).ToString();
        if (isUpdated == "false") isUpdatedProp.SetValue(itemField, "true");
    }
}

foreach (var itemField in itemList.GetType().GetFields())
        {
            var isUpdated = "false";
            var isUpdatedProp = itemField.FieldType.GetProperty("IsUpdated");
            if (isUpdatedProp != null)
            {
                isUpdated = isUpdatedProp.GetValue(itemField, null).ToString(); (*) // throw error "Object does not match target type"
                if (isUpdated == "false") isUpdatedProp.SetValue(itemField, "true");
            }
        }
Run Code Online (Sandbox Code Playgroud)

Mar*_*ell 5

让我们一次解开这一件事:

var isUpdatedProp = itemField.GetType().GetProperty("IsUpdated");
Run Code Online (Sandbox Code Playgroud)

永远.GetType()不需要在成员上使用;你想要.FieldType.PropertyType(对于属性)。并且nameof很棒:

var isUpdatedProp = itemField.FieldType.GetProperty(nameof(Foo<string>.IsUpdated));
Run Code Online (Sandbox Code Playgroud)

string这是一个假人)

然后:

 isUpdated = isUpdatedProp.GetValue(itemField, null).ToString();
Run Code Online (Sandbox Code Playgroud)

这并不是你的对象——那是该对象itemField给你的任何值。所以把它传进去;如果可能的话,将结果视为booleanitemField

var isUpdated = false;
object foo = itemField.GetValue(itemList);
...
isUpdated = (bool)isUpdatedProp.GetValue(foo, null);
Run Code Online (Sandbox Code Playgroud)

最后:

if (isUpdated == "false") isUpdatedProp.SetValue(itemField, "true");
Run Code Online (Sandbox Code Playgroud)

再说一次,对象是itemList,而属性不是string

if (!isUpdated) isUpdatedProp.SetValue(foo, true);
Run Code Online (Sandbox Code Playgroud)

Foo<T> : IFoo如果你创建IFoo一个非通用接口,那就更容易了:

interface IFoo { bool IsUpdated {get; set; } }
Run Code Online (Sandbox Code Playgroud)

那么就变成:

var foo = (IFoo)itemField.GetValue(itemList);
if(!foo.IsUpdated) foo.IsUpdated = true;
Run Code Online (Sandbox Code Playgroud)

最后,请注意,如果您没有为它们分配任何内容,FirstName则 和LastName 将为空。