【问题标题】:C# Get object inside of object that is a genericC#获取泛型对象内部的对象
【发布时间】:2016-04-14 12:46:26
【问题描述】:

我有几个包含地址对象的视图模型。该地址对象当然有 address1、address2、city、state 和 zip。
我们正在使用邮政编码地址验证系统,我希望我的所有开发人员都能够调用一个帮助类,它将嗅探视图模型对象以获取地址对象。如果没有找到,它将检查视图模型是否具有基本的 address1、address2 等属性...在任何一种情况下,我都需要它来获取属性对象地址的地址信息或获取地址属性...

所以我的辅助类方法签名如下所示:

 public void ShowVerificationWithReflection<T>(ModelStateDictionary modelState, T viewModel) where T : AMSBaseVM

然后我执行以下操作:

var objType = viewModel.GetType();
List<PropertyInfo> properties = new List<PropertyInfo>();

properties.AddRange(objType.GetProperties());

foreach (PropertyInfo property in properties)
{
    if (property.CanRead)
    {
        if (property.Name == "Address1") testAddress.Address1 = property.GetValue(viewModel, null) as string;
        if (property.Name == "Address2") testAddress.Address2 = property.GetValue(viewModel, null) as string;
        if (property.Name == "City") testAddress.City = property.GetValue(viewModel, null) as string;
        if (property.Name == "StCd") testAddress.StateCodeId = (long)property.GetValue(viewModel, null);
        if (property.Name == "Zip") testAddress.Zip = property.GetValue(viewModel, null) as string;
    }
}

这适用于作为视图模型一部分的地址属性。 现在我遇到的问题是检测视图模型是否具有这样的属性:

 public EntityAddressVM Address { get; set; }

我需要从泛型中获取该对象,然后获取其地址属性。我已经能够找到对象,但之后我就卡住了......

 bool hasEntityAddress = objType.GetProperties().Any(p => p.PropertyType == typeof(EntityAddressVM));

我需要帮助的是:

  1. 确定传入的 viewModel (mvc) 是否具有地址对象或具有 地址属性。

  2. 如果确实有地址对象,则获取地址属性,否则从 ViewModel 获取地址属性。

【问题讨论】:

  • 如何将Any 调用与SingleOrDefault 调用交换,不仅要检查属性是否存在,还要获取它。
  • 这是非常古老的代码 100+ 视图模型等等,我们不被允许深度重构。 :( 不幸的是,我对泛型没有深入的了解-尽管尝试跟上速度。但是无论哪种方式,即使使用泛型,我仍然需要获取对象地址并解析值..我被困在那部分.
  • 有人提到使用接口来简化流程。应用下面的答案后,我继续遇到各种痛点。所以我接受了这些建议并将它们与下面的答案结合起来,现在一切都很顺利。我的界面具有我所有的类和验证码所需的属性,赢家是我能够删除大量重复的、过于复杂的代码等。感谢各位的指点。

标签: c# asp.net-mvc generics reflection


【解决方案1】:

我使用一种很好的扩展方法来查看对象属性:

/// <summary>
///     Gets all public properties of an object and and puts them into dictionary.
/// </summary>
public static IDictionary<string, object> ToDictionary(this object instance)
{
    if (instance == null)
        throw new NullReferenceException();

    // if an object is dynamic it will convert to IDictionary<string, object>
    var result = instance as IDictionary<string, object>;
    if (result != null)
        return result;

    return instance.GetType()
        .GetProperties()
        .ToDictionary(x => x.Name, x => x.GetValue(instance));
}

然后你可以这样做:

var addressObject = model
    .ToDictionary()
    .FirstOrDefault(x => x.Value is EntityAddressVM)
    .Value;

如果是null,则从模型中获取地址属性。

希望这会有所帮助。

【讨论】:

  • 出现设计时错误,方法“ToDictionary”有 0 个参数,但使用 2 个参数调用。
  • 在您的.cs 文件顶部添加using System.Linq;
  • 添加了 linq 并稍微更改了代码.... 现在测试... return instance.GetType() .GetProperties() .ToDictionary(x => x.Name, x => x. GetValue(instance,null));
  • 嗯,它返回null。
  • 抱歉,已修复答案:.FirstOrDefault(x =&gt; x.Value is EntityAddressVM).。注意 x 更改为 x.Value
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多