提问人:Technetium 提问时间:1/5/2018 更新时间:1/5/2018 访问量:383
避免对具有非限定泛型类型的泛型静态类使用类名
Avoid using class name for generic static classes with unqualified generic types
问:
假设我有一个静态类,它定义了一堆委托,如下所示:
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);
}
}
}
我很想去掉实现中的前缀,因为我相信它可以提高代码的可读性。通常,我已经通过 C# 6 中的“using static”指令删除了静态类作为前缀。但是在这种情况下,它不是“完全限定的类型名称”,因此我看不到实现这一目标的方法。我很想做一些类似以下示例的事情,但这并不像人们预期的那样工作。原因是因为在 的范围之外仍未定义。Delegates<T>.
MyMethod
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
指令或其他一些技巧来避免每次使用者想要使用其属性或方法之一时都使用非限定泛型类型显式声明泛型静态类?
答:
简短的回答是否定的,我们不能那样做。
不能使用泛型类型参数编写 using 语句,该参数的类型尚不可解析为具体类型或接口类型。
来自 Microsoft 文档:
泛型类(如泛型简介中列出的 GenericList)不能按原样使用,因为它不是真正的类型;它更像是一种类型的蓝图。若要使用 GenericList,客户端代码必须通过在尖括号内指定类型参数来声明和实例化构造类型。此特定类的类型参数可以是编译器识别的任何类型。
所有参数都需要通过调用使用该泛型类型的代码来解析,并且在 using 语句的情况下,我们无法以任何方式指定应该替换哪个类型而不是泛型参数。T
T
你可以做这样的事情:但不是你想做的事情。我认为你需要坚持你在第一种方法中尝试过的东西。using static MyNamespace.Delegates<SomeType>
编辑:快速搜索后,我在这里发现了一个类似的问题。
难道你不能简单地使非泛型,并使代表本身成为泛型吗?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<>
评论
<T>
评论
Delegates<T>