繁体   English   中英

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

[英]c# generic type class cannot get the property value

使用c#reflection来获取和设置泛型对象中的通用字段的值。 但我找不到任何方法来获得这些字段的属性值 下面的代码示例:

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

问题在行(*)处获取“null”项。

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

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

var isUpdatedProp = itemField.GetType().GetProperty("IsUpdated");

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

var isUpdatedProp = itemField.FieldType.GetProperty(nameof(Foo<string>.IsUpdated));

(这里的string是假的)

然后:

 isUpdated = isUpdatedProp.GetValue(itemField, null).ToString();

itemField不是你的对象 - 这就是该对象itemField的值给你的东西。 所以通过; 如果可能的话,将结果视为布尔值

var isUpdated = false;
object foo = itemField.GetValue(itemList);
...
isUpdated = (bool)isUpdatedProp.GetValue(foo, null);

最后:

if (isUpdated == "false") isUpdatedProp.SetValue(itemField, "true");

对象再次是itemList ,属性不是string

if (!isUpdated) isUpdatedProp.SetValue(foo, true);

如果你做了Foo<T> : IFoo ,其中IFoo是一个非通用接口会更容易:

interface IFoo { bool IsUpdated {get; set; } }

然后它变成:

var foo = (IFoo)itemField.GetValue(itemList);
if(!foo.IsUpdated) foo.IsUpdated = true;

最后,请注意,如果您没有为它们指定任何内容, FirstNameLastName 将为null

您必须在itemField使用FieldType属性而不是GetType()来获取Foo类型。

https://msdn.microsoft.com/en-us/library/system.reflection.fieldinfo.fieldtype(v=vs.110).aspx

编辑:您必须获取字段类型的实例

var foo = itemField.GetValue(itemList);
var isUpdated = isUpdatedProp.GetValue(foo);

最终结果应该是这样的:

var itemList = new ItemList();
foreach (var itemField in itemList.GetType().GetFields())
{
    var isUpdatedProp = itemField.FieldType.GetProperty("IsUpdated"); 
    if (isUpdatedProp != null)
    {
        var foo = itemField.GetValue(itemList);
        isUpdated = (bool)isUpdatedProp.GetValue(foo);
        if (!isUpdated) isUpdatedProp.SetValue(foo, true);
    }
}

让我把两分钱放在试图给你另一个观点来解决问题上。

我不会为此使用反射 :为什么不用接口键入这些对象?

public interface IUpdatable
{
     bool IsUpdated { get; set; }
}

public interface IManyUpdatable 
{
     IEnumerable<IUpdatable> Updatables { get; }
}

public static class UpdatableExtensions 
{
     public static void ToggleUpdated(this IUpdatable updatable) 
     {
          if(updatable != null)
               updatable.IsUpdated = !updatable.IsUpdated
     }

     public static void ToggleUpdatables(this IEnumerable<IUpdatable> updatables)
     {
          foreach(var updatable in updatables) 
                 updatable.ToggleUpdated()

     }
}

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

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

   public Foo<string> LastName;

   IEnumerable<IUpdatable> IManyUpdatable.Updatables => new [] {  FirstName, LastName }
}

// ... somewhere in your code base:

itemList.ToggleUpdatables()

我不确定我是否已经抓住了这个想法,但似乎你是过度工程并且无缘无故地绕过打字!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM