标题说明了一切,这里有一些格式:
为什么我不能写
public bool IsHashSet(object obj)
{
return obj is HashSet<>;
}
但这没关系:
public bool IsHashSet(object obj)
{
return obj.GetType() == typeof(HashSet<>);
}
(所有仿制药也是如此,并且不限于HashSet
)
答案 0 :(得分:34)
你的功能
public bool IsHashSet(object obj)
{
return obj.GetType() == typeof(HashSet<>);
}
将为false
的每个可能值返回obj
,null
除外,在这种情况下,它会抛出NullReferenceException
。它将不检查obj
是否为哈希集。 typeof(HashSet<int>)
和typeof(HashSet<>)
是两种不同的类型。
出于同样的原因,obj is HashSet<>
被拒绝了。这完全没用。这两个函数之间的唯一区别是,一个在编译器知道的方式中是无用的,另一个在编译器不知道的方式中是无用的。
您可以使用type.IsGenericType
和type.GetGenericTypeDefinition()
,然后将后者的结果与typeof(HashSet<>)
进行比较。但是,您应该问自己这是否有用:如果obj is HashSet<int>
来自true
,obj
也会评估为HashSet<int>
。使用obj.GetType()
需要您自己检查类层次结构。
您可以编写一个可重用的辅助函数来检查其他泛型类型:
public static bool IsInstanceOfGenericType(object obj, Type genericType) {
if (obj == null)
return false;
var type = obj.GetType();
while (type != null) {
if (type.IsGenericType && type.GetGenericTypeDefinition() == genericType)
return true;
type = type.BaseType;
}
return false;
}
您可以将其称为IsInstanceOfGenericType(someObject, typeof(HashSet<>))
。
回复您的意见:
我对
HashSet<>
的理解意味着任何通用的HashSet
,所以也许这会有效typeof(HashSet<>).IsAssignableFrom(HashSet<int>)
不会。您可能正在考虑使用Java,据我所知它确实有类似的东西,但C#却没有。 HashSet<int>
和HashSet<>
是相关类型,但它们的关系与继承无关。
如果不是
的含义HashSet<>
在获得任何特定类型参数之前,它是HashSet<T>
类型。它可用于构造实际类型,例如在var t = typeof(int);
之后,typeof(HashSet<>).MakeGenericType(t)
可用于获取typeof(HashSet<int>)
。如果在编译时不知道t
,那么它会很有用。但是在这种动态类型构造之外,它没有意义。
为什么写在
typeof()
但不在is HashSet<>
中有效?
它对is HashSet<>
无效,因为它永远不会有意义。构造任何类型为HashSet<>
的对象是不可能的。
答案 1 :(得分:6)
两者都没有实际效果,只是第一个会在编译时失败。你可能想要的是这样的:
public bool IsHashSet(object obj)
{
if (obj != null)
{
var t = obj.GetType();
if (t.IsGenericType) {
return t.GetGenericTypeDefinition() == typeof(HashSet<>);
}
}
return false;
}