要了解我的要求,请考虑这些类 -
class A { }
class B {
String m_sName;
public String Name {
get { return m_sName; }
set { m_sName = value; }
}
int m_iVal;
public int Val {
get { return m_iVal; }
set { m_iVal = value; }
}
A m_objA;
public A AObject {
get { return m_objA; }
set { m_objA = value; }
}
}
现在,我需要识别传递给函数的对象的类
void MyFunc(object obj) {
Type type = obj.GetType();
foreach (PropertyInfo pi in type.GetProperties()) {
if (pi.PropertyType.IsClass) { //I need objects only
if (!type.IsGenericType && type.FullName.ToLower() == "system.string") {
object _obj = pi.GetValue(obj, null);
//do something
}
}
}
}
我不喜欢这段代码 -
if (!type.IsGenericType && type.FullName.ToLower() == "system.string") {
因为那时我必须过滤出类,如System.Int16,System.Int32,System.Boolean等。
是否有一种优雅的方式可以让我知道对象是否是由我定义的类而不是系统提供的基类?
答案 0 :(得分:1)
真的没有可靠的方法。我想到的一件事是查看定义给定类型的程序集:type.Assembly
并将其与已知程序集列表进行比较。
答案 1 :(得分:1)
一种可能的方法是使用Type.Assembly
属性并过滤掉任何未在其中一个程序集中声明的内容。这种方法的缺点是你需要在执行时知道所有程序集,这在某些(不常见)场景中可能很难。
答案 2 :(得分:0)
据我所知,没有办法知道一个类是来自BCL还是一个用户定义的类,但也许你可以从一些众所周知的框架dll中缓存一些汇编信息。
您可以遍历mscorlib.dll中的所有类,并将它们放入List中,然后根据该列表检查您的类名。
答案 3 :(得分:0)
您可以查看类型AssemblyQualifiedName
属性上Assembly
的PublicKeyToken属性。但是你必须收集框架用于不同版本的运行时的不同标记,并与之比较。
答案 4 :(得分:0)
如果您有可能,最简单的方法是使用您可以检查的属性标记您自己的类(而不是检查泛型和类型的名称)。
答案 5 :(得分:0)
我有一个可行的廉价而快速的解决方案:
if( type.IsClass && ! type.IsSealed )
System.String对象是一个类,但它也是为了继承密封。只要您不在代码中使用密封类,这就可以工作。