Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does the following C# code do?

Tags:

c#

generics

I ran across the following class in a C# XNA graphics api and I am not sure what it does or that it needs to be so obscure. (T is constrained to be a struct in a 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 makes only on call to this static class: int index = Ident.TypeIndex<T>();

like image 559
zfedoran Avatar asked Dec 03 '22 06:12

zfedoran


1 Answers

This creates a unique integer identifier for each Type, based on the order that it's accessed, in a thread-safe manner.

For example, if you do:

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

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

For example, if I run this, using:

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

It will print:

0
1
0
1

However, this could be done more effectively using Interlocked.Increment, which would avoid the need for the lock and the synchronization object completely. The following gives exactly the same answer, with no locking required:

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;
    }
} 
like image 79
Reed Copsey Avatar answered Dec 22 '22 19:12

Reed Copsey