避免对具有非限定泛型类型的通用静态类使用类名

时间:2018-01-04 19:40:37

标签: c# generics static using using-directives

假设我有一个静态类,它定义了一堆如下所示的委托:

namespace MyNamespace {

    public static class Delegates<T> {

        public delegate T Create(T input);
        public delegate T Update(T input);
        public delegate T Get(Guid id);
        public delegate bool Delete(Guid id);

    }

}

然后我有一个使用这些委托的泛型类,其中依赖类的泛型类型与静态类上的泛型类型相同。

namespace MyNamespace {

    public class MyClass<T> {

        public void MyMethod(Delegates<T>.Create create) {
            T foo = GenerateSomeT();
            create(foo);
        }

    }

}

我很想摆脱Delegates<T>.实现中的MyMethod前缀,因为我相信它可以提高代码的可读性。通常我已经从C#6中通过the "using static" directive删除了静态类作为前缀。但是在这种情况下T不是“完全限定类型名称”,所以我没有看到实现这一目标的方法。我喜欢做类似下面的例子,但这并不像人们期望的那样有效。原因是因为T仍未在MyClass范围之外定义。

using static MyNamespace.Delegates<T>;

namespace MyNamespace {

    public class MyClass<T> {

        public void MyMethod(Create create) {
            T foo = GenerateSomeT();
            create(foo);
        }

    }

}

编译器不允许我在类中移动“using static”指令。

可以使用using static指令或其他一些技巧,以避免每次消费者想要使用其属性或方法时,使用非限定泛型类型明确声明通用静态类吗

2 个答案:

答案 0 :(得分:3)

难道你不能简单地使Delegates非通用,并让代表自己变得通用吗?

public static class Delegates
{
     public delegate T Create<T> Create(T input);
     //etc
}

现在T中的MyClass<T>应该在范围内:

using static Delegates;

public class MyClass<T>
{

    public void MyMethod(Create<T> create)
    {
         //...
    }
}

但是一旦你达到这一点,你就必须意识到这是毫无意义的。代表本身就是类型,它们不需要包含在类中,因此您可以简单地执行:

public delegate T Create<T>(T t);

public class MyClass<T>
{

    public void MyMethod(Create<T> create)
    {
         //...
    }
}

不需要使用静态指令。这就是所有内置框架委托的定义方式:Func<>Action<>等。

答案 1 :(得分:1)

简短的回答是否定的,我们做不到。

您不能使用泛型类型参数编写using语句,该类型参数的类型尚不能解析为具体类型或接口类型。

来自Microsoft Docs

  

泛型类,例如泛型简介中列出的GenericList,不能按原样使用,因为它实际上不是一个类型;它更像是一种类型的蓝图。要使用GenericList,客户端代码必须通过在尖括号内指定类型参数来声明和实例化构造的类型。此特定类的type参数可以是编译器可识别的任何类型。

所有T参数都需要通过调用使用该泛型类型的代码来解析,并且在使用语句的情况下,我们无法指定应该替换哪种类型而不是泛型T参数。

您可以执行以下操作:using static MyNamespace.Delegates<SomeType>但不能执行您要执行的操作。你需要坚持你认为的第一种方法。

修改 快速搜索后,我找到了similar question here