我有一个object
类型的方法参数,它可以是几种不同的类型,包括盒装int,盒装字符串和几种不同的引用类型。在处理之前我需要安全地对对象进行打字。这对于引用类型来说没有问题,我可以使用is
或as
,但是如何将其概括为安全鸭子类型的盒装类型呢?
目前我尝试使用反射进行此操作但更愿意避免这种情况,我从断点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;
}