安全性将未知的盒装或引用类型转换为值类型

时间:2017-01-26 04:33:45

标签: c# duck-typing

问题陈述

我有一个object类型的方法参数,它可以是几种不同的类型,包括盒装int,盒装字符串和几种不同的引用类型。在处理之前我需要安全地对对象进行打字。这对于引用类型来说没有问题,我可以使用isas,但是如何将其概括为安全鸭子类型的盒装类型呢?

我的尝试

目前我尝试使用反射进行此操作但更愿意避免这种情况,我从断点Action调用LogMemberTry并且它不可靠。

public string LogMemberTry(object host, string[] options, string label = "")
{
    var result = "";
    var i = 0;

    if (host == null || host.GetType().IsValueType)
        return Pre(label) + (host?.ToString() ?? "null");

    foreach (var option in options) // return the first viable option
    {
        if((result = getValue2(host, option)?.ToString() ?? "null") != "null")
            break;
    }
    return Pre(label) + result;
}

using static System.Reflection.BindingFlags;

    private object getValue2 (object host, string member)
    {
        object retVal = null;
        const BindingFlags bindingFlags = Public | NonPublic | Instance;
        var hostType = host.GetType();
        var members = hostType.GetMember(member, bindingFlags);

        while (members.Length == 0 && hostType != typeof(object))
        {
            hostType = hostType.BaseType ?? typeof(object);
            members = hostType.GetMember(member, bindingFlags);
        }

        if (members.Length == 0) return null;

        members = members.Where(
            m =>
                (m.MemberType == MemberTypes.Field)
                || (m.MemberType == MemberTypes.Property)
        ).ToArray();


        if (members.Length == 0) return null;

        switch (members[0].MemberType) // first field or property
        {
            case MemberTypes.Property:
                retVal = hostType.GetProperty(member, bindingFlags)
                    .GetValue(host);
                break;
            case MemberTypes.Field:
                retVal = hostType.GetField(member, bindingFlags)?
                    .GetValue(host);
                break;
        }
        return retVal;
    }

0 个答案:

没有答案