如何以编程方式检查类型是结构还是类?

时间:2009-12-01 16:44:43

标签: c# .net class struct types

如果类型是结构还是类,如何以编程方式检查?

8 个答案:

答案 0 :(得分:71)

使用Type.IsValueType

  

获取一个值,该值指示Type是否为值类型。

像这样使用它:

typeof(Foo).IsValueType

或在执行时这样:

fooInstance.GetType().IsValueType

相反,还有一个Type.IsClass属性(在我看来应该被称为IsReferenceType,但无论如何)根据你测试的内容,它可能更适合你的用途。

在没有布尔否定的情况下,代码总是看起来更好,所以请使用有助于代码可读性的代码。


正如Stefan在下面指出的那样,为了正确识别结构,在enums时必须小心避免误报。 enum是值类型,因此IsValueType属性将为true以及enums返回structs

因此,如果您真的在寻找structs而不仅仅是值类型,那么您需要这样做:

Type fooType = fooInstance.GetType();
Boolean isStruct = fooType.IsValueType && !fooType.IsEnum;

答案 1 :(得分:28)

Type type = typeof(Foo);

bool isStruct = type.IsValueType && !type.IsPrimitive;
bool isClass = type.IsClass;

它仍然可以是:原始类型或接口。


编辑:关于结构的定义有很多讨论。结构和值类型实际上是相同的,因此IsValueType是正确的答案。我通常必须知道类型是否是用户定义的结构,这意味着使用关键字struct而不是基本类型实现的类型。所以我为那些遇到同样问题的人保留了答案。


编辑2 :根据C# Reference,枚举不是结构,而是任何其他值类型。因此,如何确定类型是否为结构的正确答案是:

bool isStruct = type.IsValueType && !type.IsEnum;
恕我直言,结构的定义比较符合逻辑。我实际上怀疑这个定义与实践有任何关联。

答案 2 :(得分:5)

扩展方法。对于我的代码中定义为true的内容,它会返回struct,但不会返回int这样的内容,尽管它们在技术上是结构,但不适用于我的目的。

我需要知道某个类型何时可能包含子字段或属性,但定义为struct而不是class。因为当您更改struct时,它只会更改副本,然后您必须将原件设置回更改的副本以使更改“粘住”。

public static bool IsStruct(this Type source) 
{
  return source.IsValueType && !source.IsPrimitive && !source.IsEnum;
}

答案 3 :(得分:1)

尝试以下

bool IsStruct(Type t) {
  return t.IsValueType;
}

答案 4 :(得分:0)

对于每种值类型,都有一个相应的自动生成的类类型,它派生自System.ValueType,后者又来自System.Object。请注意,值类型本身不是从任何内容派生的,而是可隐式转换到该类类型,并且该类类型的实例可以显式转换为值类型。

< / p>

考虑:

        public static int GetSomething<T>(T enumerator) where T : IEnumerator<int>
        {
            T enumerator2 = enumerator;
            enumerator.MoveNext();
            enumerator2.MoveNext();
            return enumerator2.Current;
        }

List<int>.Enumerator类型的变量上调用此例程将产生与在IEnumerator<int>类型的变量上调用此行为非常不同的行为,该变量恰好存储在其中的List<int>.Enumerator实例。尽管类型List<int>.Enumerator的变量是值类型,但存储在类型List<int>.Enumerator的变量中的IEnumerator<int>实例将表现为类类型。

答案 5 :(得分:0)

结构:

// determine if the type is a struct..
var isStruct = type.IsValueType && !type.IsEnum &&
               !type.IsEquivalentTo(typeof(decimal)) && 
               !type.IsPrimitive;

课程:

var isClass = type.IsClass;

答案:

var isClassOrStruct = isStruct | isClass;

答案 6 :(得分:0)

{
  "seqnum": 2,
  "event": "updated",
  "channel": "prices",
  "symbol": "BTC-USD",
  "price": [1559039640, 8697.24, 8700.98, 8697.27, 8700.98, 0.431]
}

答案 7 :(得分:0)

我认为应该是这样的:

是结构

public bool IsStructure(Type LocalType)
{
    bool result = false;
    if (LocalType.IsValueType)
    {
        //Is Value Type
        if (!LocalType.IsPrimitive)
        {
            /* Is not primitive. Remember that primitives are:
            Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32,
            Int64, UInt64, IntPtr, UIntPtr, Char, Double, Single.
            This way, could still be Decimal, Date or Enum. */
            if (!LocalType == typeof(decimal))
            {
                //Is not Decimal
                if (!LocalType == typeof(DateTime))
                {
                    //Is not Date
                    if (!LocalType.IsEnum)
                    {
                        //Is not Enum. Consequently it is a structure.
                        result = true;
                    }
                }
            }
        }
    }
    return result;
}

它是一类

public bool IsClass(Type LocalType)
{
    bool result = false;
    if (LocalType.IsClass)
    {
        //Is Class or Delegate
        if (LocalType.GetType != typeof(Delegate))
            result = true;
    }
    return result;
}