为什么我不能写if(object是HashSet <>)但是如果我写的话也没关系(object.GetType()== typeof(HashSet <>))

Ran*_*dom 19 c# generics

标题说明了一切,这里有一些格式:

为什么我不能写

public bool IsHashSet(object obj)
{
    return obj is HashSet<>;
}
Run Code Online (Sandbox Code Playgroud)

但这没关系:

public bool IsHashSet(object obj)
{
    return obj.GetType() == typeof(HashSet<>);
}
Run Code Online (Sandbox Code Playgroud)

(所有仿制药都是如此,并不限于此HashSet)

小智 34

你的功能

public bool IsHashSet(object obj)
{
  return obj.GetType() == typeof(HashSet<>);
}
Run Code Online (Sandbox Code Playgroud)

将返回false每个可能的值obj,除了null,在这种情况下,它将抛出一个NullReferenceException.它不会检查是否obj是哈希集.typeof(HashSet<int>)并且typeof(HashSet<>)是两种不同的类型.

出于同样的原因obj is HashSet<> 被拒绝了.这完全没用.这两个函数之间的唯一区别是,一个在编译器知道的方式中是无用的,另一个在编译器不知道的方式中是无用的.

你可以使用type.IsGenericTypetype.GetGenericTypeDefinition(),然后比较后者的结果typeof(HashSet<>).但是,您应该问自己这是否有用:obj is HashSet<int>还会评估trueif 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;
}
Run Code Online (Sandbox Code Playgroud)

你可以称之为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在编译时不知道它可能很有用.但是在这种动态类型构造之外,它没有意义.

为什么写入a typeof()而不是写入是有效的is HashSet<>

它无效,is HashSet<>因为它永远不会有意义.构造任何类型的对象是不可能的HashSet<>.

  • 呵呵,虽然我明白,谁张贴他们只是因为upvoting多个答案实际上是什么,一般是不会接受的,并且可能导致正在采取的行动对那些票.很高兴听到它有所帮助. (4认同)

Mat*_*and 6

两者都没有实际工作,只是第一个在编译时会失败.你可能想要的是这样的:

public bool IsHashSet(object obj)
{
    if (obj != null) 
    {
        var t = obj.GetType();
        if (t.IsGenericType) {
            return t.GetGenericTypeDefinition() == typeof(HashSet<>);
        }
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

  • 根本没有回答这个问题 (4认同)