views:

591

answers:

4

I don't think that this could be done in C#, but posting this just to make sure. Here's my problem. I would like to do something like this in C#:

var x = 10;
var l = new List<typeof(x)>();

or

var x = 10;
var t = typeof(x);
var l = new List<t>();

But of course this doesn't work. Although this shouldn't be a problem as the type t is resolved at compile time. I understand that this can be solved with reflection, but as types are known at compile time using reflection would be overkill.

+2  A: 

Defining generics is done like this in C#:

var someList = new List<int>();

You can not define generics like this:

var x = 1;
var someType = typeof(x);
var someList = new List<someType>();

because you're specifying the type at run time in this case, not compile time. C# doesn't support that.

Joseph
You just repeated what Max stated in the question.
Anton Tykhyy
@Anton No I didn't, Max is under the impression that typeof(x) is resolved at compile time, which is not correct.
Joseph
@Joseph: Are you sure? I know that x.GetType() is resolved at runtime, because it gives the type that x is currently refering to, but I thought typeof(x) will always give the type of the variable, as defined at compile time.
Steven Sudit
In the case of the sample code, the type of someType is System.Type, so it works, but not as desired. You get a list of types, not a list of ints.
Steven Sudit
@Joseph: actually `typeof(x)` is a syntax error, which I think Max knew before posting. He didn't write `x.GetType()` (which is what you want to write in your second example) and he knows reflection.
Anton Tykhyy
Yes, I know how to define generics. What I was trying to do is to get rid of redundancy in type declarations.I'm not specifying types at runtime. Type inference is resolved at compile time and typeof() operator is also resolves at compile time. It's the GetType() method that resolves type at run time.
Max
+5  A: 

You're trying to get .Net to set a generic type using a run-time operator. As you know, that won't work. Generics types must be set at compile time.

Joel Coehoorn
+26  A: 
public static List<T> CreateCompatibleList<T> (T t)
{
    return new List<T> () ;
}

var x = 10 ;
var l = CreateCompatibleList (x) ;
Anton Tykhyy
Nice one. Really like this solution.
Dykam
+1 Sneaky, and works for this case. :)
280Z28
Muy clevar! Nicely done.
Nathan Taylor
That's it. Great! Thanks. Although it seems that this is something C# team should work on.
Max
One thing you could add to this is to make it an extension method. Then you could use syntax like this: var l = x.CreateList()
Steven Sudit
+1  A: 

You can't do it exactly how you are asking, but with a little reflection you can accomplish the same thing

Type genericType = typeof(List<>);
Type[] type = new Type[] { typeof(int) };
Type instanceType = genericType.MakeGenericType(type);
object instance = Activator.CreateInstance(instanceType );
var l = (List<int>)instance;
Bob
`(List<string>)` in the last line defeats your purpose. But yes, this is useful in certain cases.
Anton Tykhyy