简体   繁体   English

如何使用.NET中的反射来确定和检查程序集中的类型是自定义类型还是基元类型?

[英]How to determine and check whether a type in assembly is Custom type or Primitive type using reflection in .NET?

Is it possible to check at runtime whether given type is Custom data type or one of primitive data types of .NET? 是否可以在运行时检查给定类型是自定义数据类型还是.NET的原始数据类型之一?

I have defined user defined types in assembly and those all types are some structs. 我在程序集中定义了用户定义的类型,所有类型都是一些结构。 I need to call the methods of user defined types of whome parameters are those structs. 我需要调用用户定义类型的方法,其中的参数是那些结构。 So this needs to fill the data accordingly before calling those function at runtime using reflection. 因此,在使用反射在运行时调用这些函数之前,需要相应地填充数据。

Now Is there any method available in reflection by which we can track that given data type is custom or primitive data type. 现在是否有任何反射方法可用于跟踪给定数据类型是自定义数据类型还是原始数据类型。 I know about IsClass attribute, but my targeted user defined data types are not classes , these public are STRUCTS. 我知道IsClass属性,但我的目标用户定义数据类型不是类,这些公共是STRUCTS。

I'd go with something like: 我会选择以下内容:

static bool IsFundamental(this Type type)
{
    return type.IsPrimitive || type.Equals(typeof(string)) || type.Equals(typeof(DateTime));
}

The choice of string and DateTime as additions to the types for which IsPrimitive returns true , though, is a subjective matter since there is no absolute list... the ultimate choice is yours (you might want to include decimal as well, for example); 然而,选择stringDateTime作为IsPrimitive返回true的类型的IsPrimitive是一个主观问题,因为没有绝对列表...最终的选择是你的(例如,你可能想要包括decimal ) ; and it should definitely be documented (at least in a comment, preferably an XML one). 和它绝对应该记录(至少在一个评论,优选为XML一个)。

Based on information in this question , you can accomplish this using the following code: 根据此问题中的信息,您可以使用以下代码完成此操作:

public static class TypeExtensions
{
    private static List<byte[]> tokens = new List<byte[]>() 
    {
        new byte[] {0xb7, 0x7a, 0x5c, 0x56, 0x19, 0x34, 0xe0, 0x89},
        new byte[] {0x31, 0xbf, 0x38, 0x56, 0xad, 0x36, 0x4e, 0x35},
        new byte[] {0xb0, 0x3f, 0x5f, 0x7f, 0x11, 0xd5, 0x0a, 0x3a}
    };

    public static bool IsFrameworkType(this Type type)
    {
        if (type == null) { throw new ArgumentNullException("type"); }

        byte[] publicKeyToken = type.Assembly.GetName().GetPublicKeyToken();    

        return publicKeyToken != null && publicKeyToken.Length == 8
           && tokens.Contains(publicKeyToken, new ByteArrayEqualityComparer());
    }
}

The set of public key tokens are valid for .NET 2.0 and higher (including .NET 4.0). 公钥标记集对.NET 2.0及更高版本(包括.NET 4.0)有效。 The ByteArrayEqualityComparer class looks like: ByteArrayEqualityComparer类如下所示:

public class ByteArrayEqualityComparer : EqualityComparer<byte[]>
{
    public override bool Equals(byte[] x, byte[] y)
    {
        return x != null && y != null
                    && x.Length == 8 && y.Length == 8
                    && x[0] == y[0]
                    && x[1] == y[1]
                    && x[2] == y[2]
                    && x[3] == y[3]
                    && x[4] == y[4]
                    && x[5] == y[5]
                    && x[6] == y[6]
                    && x[7] == y[7];
    }

    public override int GetHashCode(byte[] obj)
    {
        return obj.GetHashCode();
    }
}

You would then use this method like: 然后,您将使用此方法,如:

Debug.WriteLine("Is type `string` a .NET Framework type? {0}",
   typeof(string).IsFrameworkType());

You might be able to get by, by checking the full name of the type or the assembly as below, 您可以通过检查类型或程序集的全名来实现,如下所示,

if(obj.GetType().Assembly.FullName.Contains("MyAssembly"))
{
    //User-defined type
}
else if(obj.GetType().FullName.StartsWith("System."))
{
    //.NET type
}

The easiest way I followed is to verify the namespace to figure out if its one of your custom types. 我遵循的最简单方法是验证命名空间,以确定它是否是您的自定义类型之一。 For instance, your namespace might be "YourCompany.YourDepartment" and this can be verified against the type's Namespace. 例如,您的命名空间可能是“YourCompany.YourDepartment”,可以根据类型的命名空间进行验证。

A very simple, rudimentary way of determing whether a type is provided by the BCL/CLR is: 确定BCL / CLR是否提供类型的一种非常简单的基本方法是:

var type = typeof(int);
var isSystemType = type.Assembly.FullName.StartsWith("mscorlib");

Bear in mind that using Type.IsPrimitive will return false for System.String , so it depends on what definition of "primitive" you're using as to whether it's suitable or not. 请记住,使用Type.IsPrimitive将为System.String返回false ,因此它取决于您使用的“原始”的定义是否合适。

It sounds like you have a need to distinguish between types that you made yourself from everything else. 听起来你需要区分你自己制作的类型。 Just create a custom attribute that you put on each of your types, like this: 只需创建一个自定义属性,放在每个类型上,如下所示:

[CustomAttribute]
struct MyDataType
{
....
}

Another option is to create an interface that all of your own custom types implement. 另一种选择是创建一个所有自定义类型实现的接口。 Then it's easy to see if you need to do something special with that instance just by doing if (x is ICustom) ... . 然后很容易看出你是否需要通过if (x is ICustom) ...对该实例做一些特殊的事情if (x is ICustom) ...

If it's possible to put them all in the same namespace or assembly, those are also easy to check with reflection. 如果可以将它们全部放在同一个命名空间或程序集中,那么这些也很容易通过反射来检查。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用反射从基本类型确定复杂类型 - determine complex type from a primitive type using reflection 使用反射来确定.Net类型在内存中的布局方式 - Using reflection to determine how a .Net type is layed out in memory 如何动态确定类型是否是使用反射的接口? - How to determine dynamically if type is an Interface using reflection? 如何获取.Net中给定类型的程序集(System.Reflection.Assembly)? - How to get the assembly (System.Reflection.Assembly) for a given type in .Net? 如何确定接口类型是否实现自定义样式 - How to determine whether an interface type implements a custom attibute 使用反射从程序集加载中获取类型 - Get type from assembly load using reflection 如何使用反射确定已实现接口的通用类型? - How do I determine the generic type of an implemented interface using reflection? 如何在不使用反射的情况下确定对象是否为KeyValue &lt;,&gt;对的某种类型 - How to determine if an object is some type of KeyValue<,> pair without using reflection 如果一个类是WinRT类型,如何确定使用C#反射 - How to determine using C# Reflection if a class is a WinRT type 解析使用反射从字符串中获得的任何原始类型 - Parse any primitive type garnered using Reflection from a string
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM