开发者

How to determine if a object type is a built in system type

I am writing a simple List<t> to CSV converter. My converter checks the all the t's in List and grabs all public properties and places them into the CSV.

My code works great (as intended) when you will use a simple class with a few properties.

I would like to get the List<t> to CSV converter to also accept the System types such as String and Integer. With these system types I do not want to get their public properties (such as Length, Chars etc). Thus I would like to check if the object is a System type. By System type I mean one of the built in .Net types such as string, int32, double etc.

Using GetType() I can find out the following:

string myName = "Joe Doe";

bool isPrimitive = myName.Get开发者_如何学PythonType().IsPrimitive; // False
bool isSealed = myName.GetType().IsSealed; // True 
// From memory all of the System types are sealed.
bool isValueType = myName.GetType().IsValueType; // False

// LinqPad users: isPrimitive.Dump();isSealed.Dump();isValueType.Dump();

How can I find if variable myName is a built in System type? (assuming we don't know its a string)


Here are a few of the several possibilities:

  • myName.GetType().Namespace == "System"
  • myName.GetType().Namespace.StartsWith("System")
  • myName.GetType().Module.ScopeName == "CommonLanguageRuntimeLibrary"


myName.GetType().Namespace
This will return System if it is an in-built type.


If you are unable to define precisely what a "built in system type" is then it seems likely that you won't know what types are in any answer given. More probably what you want to do is just have a list of the types that you don't want to do this with. Have a "IsSimpleType" method that just does a check against various types.

The other thing that you may be looking for is Primitive Types. If so look at:

Type.IsPrimitive (http://msdn.microsoft.com/en-us/library/system.type.isprimitive.aspx)

The primitive types are Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, and Single.

This doesn't include string but you could add that on manually...

See also How To Test if Type is Primitive


Namespace-based methods potentially may cause collisions.

There is an another reliable and simple way:

static bool IsSystemType(this Type type) => type.Assembly == typeof(object).Assembly;

Or a little bit more optimal, caching the system assembly:

static readonly Assembly SystemAssembly = typeof(object).Assembly;

static bool IsSystemType(this Type type) => type.Assembly == SystemAssembly;


I think this is the best possibility:

private static bool IsBulitinType(Type type)
{
    return (type == typeof(object) || Type.GetTypeCode(type) != TypeCode.Object);
}


I was building something reflectively and found that the IsSecurityCritical property seemed to work for this purpose; however, this was only because the trust-level for my assembly wasn't high enough to flip that bit.

A bit of a laugh; thankfully I found this question and will be adjusting accordingly.

Note: The IsSecurityCritical property only exists if .NetFramework > 4

I will likely go with; the following from a previous answer.

myName.GetType().Module.ScopeName == "CommonLanguageRuntimeLibrary"

But, with a couple tweaks; such as making it an extension method on Type and using a const for CommonLanguageRuntimeLibrary


Given the caveats surrounding the existing answers, I am going to suggest a Windows only solution:

public static class TypeExt {
    public static bool IsBuiltin(this Type aType) => new[] { "/dotnet/shared/microsoft", "/windows/microsoft.net" }.Any(p => aType.Assembly.CodeBase.ToLowerInvariant().Contains(p));
}

Presumably there is a similar path on other supported operating systems.


I prefer

colType.FullName.StartsWith("System")

rather then

colType.Namespace.StartsWith("System")

becose Namespace may be null.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜