问题
Is it possible in C# to create an array of unspecified generic types? Something along the lines of this:
ShaderParam<>[] params = new ShaderParam<>[5];
params[0] = new ShaderParam<float>();
Or is this simply not possible due to C#'s strong typing?
回答1:
It's not possible. In the case where the generic type is under your control, you can create a non-generic base type, e.g.
ShaderParam[] params = new ShaderParam[5]; // Note no generics
params[0] = new ShaderParam<float>(); // If ShaderParam<T> extends ShaderParam
My guess is that this is an XNA type you have no control over though.
回答2:
You could use a covariant interface for ShaderParam<T>
:
interface IShaderParam<out T> { ... }
class ShaderParam<T> : IShaderParam<T> { ... }
Usage:
IShaderParam<object>[] parameters = new IShaderParam<object>[5];
parameters[0] = new ShaderParam<string>(); // <- note the string!
But you can't use it with value types like float
in your example. Covariance is only valid with reference types (like string
in my example). You also can't use it if the type parameter appears in contravariant positions, e.g. as method parameters. Still, it might be good to know about this technique.
回答3:
That wouldn't make sense.
What would happen if you write params[3]
?
What type would it be?
You may want to create a non-generic base class or interface and use an array of them.
回答4:
This is possible in a generic class or a generic extension method where T is defined:
ShaderParam<T>[] params = new ShaderParam<T>[5];
回答5:
No, the concept ShaderParam<>
is meaningless as far as an instantiated type is concerned. In other words, a concrete ShaderParam<float>
is not an instance of ShaderParam<>
. Therefore, the declared type of the array would be illegal for holding that instance. (Above and beyond the fact that it's already illegal syntax to begin with.)
回答6:
create an array of unspecified generic types:
Object[] ArrayOfObjects = new Object[5];
ArrayOfObjects[0] = 1.1;
ArrayOfObjects[1] = "Hello,I am an Object";
ArrayOfObjects[2] = new DateTime(1000000);
System.Console.WriteLine(ArrayOfObjects[0]);
System.Console.WriteLine(ArrayOfObjects[1]);
System.Console.WriteLine(ArrayOfObjects[2]);
If you need to perform some type specific actions on the object you could use Reflection
Hope this helps.
回答7:
Rather late to the game, but here's how: http://www.codeproject.com/Articles/1097830/Down-the-Rabbit-Hole-with-Array-of-Generics
回答8:
Not directly. A closed generic is a specific "type" behind the scenes, so even an open generic is too general to be a "strong type".
The best solution I can think of, which I've used before, is to create a non-generic ancestor to the generic class. Whether that solution will function depends on what you plan to use the array for.
来源:https://stackoverflow.com/questions/5222828/array-of-a-generic-class-with-unspecified-type