【问题标题】:C# - static types cannot be used as type argumentsC# - 静态类型不能用作类型参数
【发布时间】:2011-05-02 14:46:39
【问题描述】:

我有一个通用类,它可以帮助我检查参数值

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)));
        }
    }
}

但是当我尝试将它与静态类一起使用时:

internal static class Class1
{
    private static Argument<Class1> _arg;
}

我收到了这个错误(编译时):

静态类型不能用作类型参数

我做错了什么?

【问题讨论】:

    标签: c# generics static


    【解决方案1】:

    这是故意的。

    静态类试图防止不当使用,因此在几乎所有情况下,您都不能在通常需要类型的 instance 的情况下使用它们...并且包括类型论据。

    请参阅"Static classes" of the C# 6 spec 部分,了解可以引用静态类类型的非常有限的情况。

    【讨论】:

    • 我的静态类不是静态的,但使用私有构造函数可以完成这项工作吗?所以没有人可以实例化它,但它是非静态的。这是执行它的好方法吗? (感谢本节,我已阅读)
    • @Arnaud F.:那会工作 - 但是你使用 type 参数是为了什么?它有什么意义?貌似只有InternalTraceHelper用过,不知道是什么情况。
    • InternalTraceHelperTrace.Write(),参数类型用于定义跟踪的类别。可以替换为Trace.WriteLine("a message", typeof(T).FullName); // Where T = Class1
    • @Arnaud F.:听起来您可能想要一个非通用版本的 InternalTraceHelper,它采用 Type 代替。实际上,您可以使整个类成为非泛型,只需使用泛型方法来简化创建:InternalTraceHelper.Create&lt;Foo&gt; 将调用new InternalTraceHelper(typeof(T)),其中T 是该方法的类型参数。
    • 非常感谢大师的指点!
    【解决方案2】:

    泛型仅适用于实例,不适用于静态类。

    【讨论】:

    • 有解决方法吗?我该如何管理它?我不会在静态类中“手动”检查并在非静态类中使用Argument&lt;T&gt;...
    • 没有,除了使用System.Type
    • @Arnaud,你不能将静态类型作为参数传递,所以我看不出你什么时候想要Argument&lt;StaticType&gt;,除非我被你的类名误导了。
    • 我的静态类不是静态的,但使用私有构造函数可以完成这项工作吗?所以没有人可以实例化它,但它是非静态的。这是执行它的好方法吗?
    • 是的,这绝对是一个信息丰富的答案。你为什么要写这么长的文字?
    【解决方案3】:

    由于无法实例化静态类,它永远无法创建具有静态类型的Argument&lt;T&gt;

    【讨论】:

    • 这是不正确的。 ILogger 是一个示例,其中类成为记录器在发出诊断时使用的类别。这是一条愚蠢的规则。
    • @Quarkly,你找到解决办法了吗?考虑现在只使类非静态
    【解决方案4】:

    您做错的是将静态类型用作泛型类型参数。

    【讨论】:

      【解决方案5】:

      由于静态类没有实例成员,我关心的是我要对它们做什么。

      我相信,由于您不能使用静态类作为泛型参数,我相信您需要使用扩展方法而不是泛型类来做到这一点。

      https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods

      【讨论】:

        猜你喜欢
        • 2012-03-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多