简体   繁体   中英

C# Reflection get value from ICollection

i'm struggling with a problem and I'm unable to find a solution.

In a certain moment of my code, a SqlException is thrown.

I have created a method using reflection to iterate through all the properties from any exception and perform some logic, but I'm having an issue with this one.

One of its members call Errors , that inherits from SqlErrorCollection . (According to MSDN documentation, the class definition is

[SerializableAttribute]
[ListBindableAttribute(false)]
public sealed class SqlErrorCollection : ICollection, 

The code I use to check if a property is a list doesn't work for this property:

if (typeof(IEnumerable).IsAssignableFrom(prop.PropertyType)
    && typeof(ICollection).IsAssignableFrom(prop.PropertyType)
    && prop.PropertyType.IsGenericType)

And when I will get it value using the code below

property.GetValue(myObject, null);

an TargetParameterCountException (Parameters count mismatch) is raised.

Anyone know why?

Looping through the errors in SqlException is very easy. if that's what you're after, here you go.

private string GenerateMessage(SqlException ex)
{
    StringBuilder builder = new StringBuilder();
    foreach (SqlError error in ex.Errors)
    {
        builder.Append(error.ToString());
    }

    return builder.ToString();
}

prop.PropertyType.IsGenericType check will return false, since SqlErrorsCollection is non-generic. As for second part of the problem - I was unable to reproduce this exception when getting property value. Following code executes without exceptions:

// create inner sql error collection instance through reflection
var sqlErrorCollCtor = typeof(SqlErrorCollection).GetConstructors(
  BindingFlags.Instance 
| BindingFlags.NonPublic 
| BindingFlags.NonPublic).FirstOrDefault();

var errorCollection = (SqlErrorCollection)sqlErrorCollCtor.Invoke(null);

// create sql exception instance through reflection
var sqlExceptionCtor = typeof(SqlException).GetConstructors(
  BindingFlags.Instance 
| BindingFlags.NonPublic 
| BindingFlags.NonPublic).FirstOrDefault();

var exception = sqlExceptionCtor.Invoke(
  new object[] { "Test", errorCollection, null, new Guid() });

// retrieve Errors property
var prop = exception.GetType().GetProperty("Errors");

if (typeof(IEnumerable).IsAssignableFrom(prop.PropertyType)
    && typeof(ICollection).IsAssignableFrom(prop.PropertyType) )
    // && prop.PropertyType.IsGenericType)
{
    var val = prop.GetValue(exception, null);
    Console.WriteLine(val);
}

Could it be that you are retrieving value from another object, not SqlException?

Due to the insight provided by pmcoltrane, the Error property is an indexed property. The article iterating through an indexed property (Reflection) helped to solve my problem.

Thanks for the help

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