C# - static types cannot be used as type arguments
41,867
Solution 1
This is deliberate.
Static classes try to prevent inappropriate use, so in almost all situations, you can't use them in situations where you'd normally want an instance of the type... and that includes type arguments.
See section "Static classes" of the C# 6 spec for the very limited set of situations in which you can refer to static class types.
Solution 2
Generics only work with instances, not static classes.
Solution 3
Since static classes cannot be instantiated, it can never create Argument<T>
with a static type.
Comments
-
Arnaud F. over 3 years
I've a generic class, that helps me to do checks on argument values
internal sealed class Argument<T> where T : class { private void TraceAndThrow(Exception ex) { new InternalTraceHelper<T>().WriteError(ex); throw ex; } internal void ThrowNull(object value, string argName) { if (ReferenceEquals(value, null)) { TraceAndThrow(new ArgumentNullException(argName)); } } internal void ThrowIf(bool condition, string argName) { if (condition) { TraceAndThrow(new ArgumentException(null, argName)); } } internal void ThrowNotInEnum(Type enumType, object value) { if (!Enum.IsDefined(enumType, value)) { TraceAndThrow(new ArgumentOutOfRangeException(Resources.ArgEnumIllegalVal.InvariantFormat(value))); } } }
But when I try to use it with a static class :
internal static class Class1 { private static Argument<Class1> _arg; }
I got this error (at compilation):
static types cannot be used as type arguments
What I'm doing wrong?
-
Arnaud F. about 13 yearsIs there a workaround? How can I manage it? I wouldn't check "manually" in static classes and using
Argument<T>
in the non-static one... -
Daniel A. White about 13 yearsNo there isn't other than using
System.Type
. -
JSBձոգչ about 13 years@Arnaud, you can't pass static types as arguments, so I fail to see when you'd ever want to have an
Argument<StaticType>
, unless I'm being misled by your class name. -
Arnaud F. about 13 yearsDoing my static classes non static but with a private constructor will do the job? So no one can instanciate it, but is non-static. Is this a good way to perform it?
-
Arnaud F. about 13 yearsDoing my static classes non static but with a private constructor will do the job? So no one can instanciate it, but is non-static. Is this a good way to perform it? (Thanks for the section, I've read it)
-
Jon Skeet about 13 years@Arnaud F.: Well that would work - but what are you using the type argument for? What's the point of it? It looks like it's only used by
InternalTraceHelper
, and we don't know what that's like. -
Arnaud F. about 13 years
InternalTraceHelper
doesTrace.Write()
, the argument type is used to define the category of the trace. Can be replaced byTrace.WriteLine("a message", typeof(T).FullName); // Where T = Class1
-
Jon Skeet about 13 years@Arnaud F.: It sounds like you possibly want a non-generic version of InternalTraceHelper which takes a
Type
instead. In fact, you could make the whole class non-generic, just with a generic method to make creation simpler:InternalTraceHelper.Create<Foo>
would callnew InternalTraceHelper(typeof(T))
whereT
is the type parameter for the method. -
Arnaud F. about 13 yearsThanks a lot for the tip Master !
-
Selman Genç about 7 yearsyeah this is definitely an informative answer. why did u bother to write such a long text ?
-
Quarkly about 5 yearsThat is incorrect. ILogger<T> is an example where the class becomes a category for the logger to use when emitting diagnostics. This is a stupid rule.
-
ElFik over 4 years@Quarkly, did you find a way around it? considering just making the class non-static now