简体   繁体   中英

C# Get object inside of object that is a generic

I have several View Models that contain a address object. That address object of course has address1, address2, city, state, and zip.
We are using the postal code address verification system, and I want all of my developers to be able to call a helper class, that will sniff View Model object for a address object. If it does not find it, it will then check to see if the view model has basic address1, address2 and etc properties... In either case I need it to get the address information for either the property object address or get the address properties...

So my helper class method signature looks like this:

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

I then do the following:

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

This works for the address properties that part of the View Model. Now what I am stumbling with is detecting if the View Model has a property like this:

 public EntityAddressVM Address { get; set; }

I need to get that object from the generic and then get its address properties. I have been able to find the object, but after that I get stuck...

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

What I am needing help with is:

  1. Determine if incoming viewModel (mvc) has a address object or has address properties.

  2. If it does have address Object, get the address properties otherwise get the address properties from the ViewModel.

There is one nice extension method that I use to look at objects properties:

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

Then you can do something like this:

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

If its null then get Address properties from model.

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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