public void Test<T>()
{
Console.WriteLine(nameof(T));
}
Test<int>();
这段代码实际上打印了T
而不是int
,这一点用处都没有。我希望获得一个实际使用的泛型类型参数的名称,而不使用反射(typeof
,然后对Type
变量进行操作,等等)。
我读到泛型的要点是在编译时用不同的类型定义代码的变体。nameof
也是一个编译时操作符。在这种情况下,知道T是int
就足够了。除了必须从用户端完成之外,肯定还有其他方法来完成(例如Test<int>(nameof(int))
)
如果有人对这个用例感兴趣,除了调试之外,我还想用项目的类名作为关键字来向字典中添加一些东西。这个字典正好有每个形状的一个。
public AddShape<T>(T shape) where T : Shape
{
dict.Add(nameof(T), shape.SerializableShape);
}
5条答案
按热度按时间qlfbtfca1#
nameof
结构用于在编译时确定一个类型、变量、字段等的 name。当你在运行时需要一个 type 时,它没有帮助。你可以做的只是使用对象的类型信息:soat7uwm2#
因为
nameof
在编译时使用类型信息,并将使用该信息中的名称作为字符串,但对于泛型类型T
,编译器无法在编译时计算出这一点,因为它将作为参数传递,从那里它将被使用,因为它可以是Shape
或它的任何子类型,这就是它将在运行时初始化的原因,所以这就是为什么不能像上面那样使用它的原因。我还发现这也将有助于相关:
https://stackoverflow.com/a/29878933/1875256
希望能有所帮助
sz81bmfz3#
documentation对
nameof
的执行时间不是很清楚,但是可以找到下面的句子:不幸的是,typeof不是像nameof那样的常量表达式
我们在C#语言存储库中也有规范,其中规定:
nameof_expression是字符串类型的常量表达式,在运行时不起作用。
这就是为什么
nameof(T)
返回"T"
而不是实际的类型名的原因。因此,您需要另一种方法在运行时获得类型名。这就是typeof
操作符。根据规范:typeof运算子可以用在型别参数上。结果是系结至型别参数之执行阶段型别的System.Type对象。
正如您所看到的,结果完全取决于
WriteType<T>
方法的绑定类型。这意味着如果绑定类型是Shape
,则将打印"Shape"
。因此,当您迭代Shape
的集合时,T
的绑定类型将是Shape
而不是Circle
。因为T
被推导为Shape
。如果要获取当前形状的运行时类型,则应使用the
GetType
method。从thetypeof
operator documentation:若要获取表达式的运行时类型,可以使用.NET Framework方法GetType,如下面的示例所示
这是你的情况。你既不需要
typeof
也不需要nameof
。你甚至不需要泛型,因为你想要当前示例的运行时类型。您失败了,因为您使用过C++,它也是静态类型的,但有区别。正如您所知,在C++中,模板参数是在编译时替换的,而在.NET中,它们是在运行时替换的。我建议您阅读Differences Between C++ Templates and C# Generics。
8qgya5xd4#
使用
typeof(T)
作为你的键,nameof
,如果它有效的话,实际上将是一个可怕的选择,因为它返回的名称是不合格的,所以没有任何东西可以确保键是唯一的。j7dteeu85#
使用typeof(T)。仅名称...不需要形状