What does the following C # code do?

I came across the following class in the C # XNA graphical shell, and I'm not sure what it does or what it should be so obscure. (T is limited by the structure in the parent class)

static class Ident { static object sync = new object(); static volatile int index = 0; static int Index { get { lock (sync) return index++; } } class Type<T> { public static int id = Index; } public static int TypeIndex<T>() { return Type<T>.id; } } 

The API does only when this static class is called: int index = Ident.TypeIndex<T>();

+4
source share
3 answers

This creates a unique integer identifier for each type based on the order it accesses in thread safe mode.

For example, if you do:

 int myClassId = Ident.TypeIndex<MyClass>(); int mySecondClssId = Ident.TypeIndex<MySecondClass>(); 

You will get 2 "TypeIndex" numbers (with mySecondClassId at least 1 more than myClassId, but potentially more, due to streaming). Later, if you call it again with the same class, it will return the same TypeIndex for that class.

For example, if I ran this using:

 Console.WriteLine(Ident.TypeIndex<Program>()); Console.WriteLine(Ident.TypeIndex<Test>()); Console.WriteLine(Ident.TypeIndex<Program>()); Console.WriteLine(Ident.TypeIndex<Test>()); 

He will print:

 0 1 0 1 

However, this could be done more efficiently using Interlocked.Increment , which completely eliminates the need for locking and a synchronization object. The following gives exactly the same answer, without the need for blocking:

 static class Ident { static int index = -1; static int Index { get { return Interlocked.Increment(ref index); } } private static class Type<T> { public static int id = Index; } public static int TypeIndex<T>() { return Type<T>.id; } } 
+8
source

It assigns a unique identifier (static) and thread-safe (blocking synchronization object + mutable index) for each other type T.

example:

 Console.WriteLine(Ident.TypeIndex<int>()); // 0 Console.WriteLine(Ident.TypeIndex<string>()); // 1 Console.WriteLine(Ident.TypeIndex<long>()); // 2 Console.WriteLine(Ident.TypeIndex<int>()); // 0 

Volatile is used to ensure that the current thread does not cache the index value, and blocking prevents more than one thread from accessing it.

+8
source

It returns the number of times Ident.TypeIndex was called, possibly to assign a unique number to each object.

Because of how they use generics, there must be a different sequence of numbers for each type of T. So you can have circle # 1, circle # 2 and square # 1.

+2
source

All Articles