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.

Share:
41,867
Arnaud F.
Author by

Arnaud F.

(c) Feel good Inc.

Updated on December 31, 2020

Comments

  • Arnaud F.
    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.
    Arnaud F. about 13 years
    Is 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
    Daniel A. White about 13 years
    No there isn't other than using System.Type.
  • JSBձոգչ
    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.
    Arnaud F. about 13 years
    Doing 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.
    Arnaud F. about 13 years
    Doing 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
    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.
    Arnaud F. about 13 years
    InternalTraceHelper does Trace.Write(), the argument type is used to define the category of the trace. Can be replaced by Trace.WriteLine("a message", typeof(T).FullName); // Where T = Class1
  • Jon Skeet
    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 call new InternalTraceHelper(typeof(T)) where T is the type parameter for the method.
  • Arnaud F.
    Arnaud F. about 13 years
    Thanks a lot for the tip Master !
  • Selman Genç
    Selman Genç about 7 years
    yeah this is definitely an informative answer. why did u bother to write such a long text ?
  • Quarkly
    Quarkly about 5 years
    That 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
    ElFik over 4 years
    @Quarkly, did you find a way around it? considering just making the class non-static now