C#/.NET:“typeof(variable)”是一种可能的语言功能吗?
在一些单独的场合,我尝试将声明的类型从变量中导出,距离其声明相对较远,却发现 typeof(T)
仅适用于类型名称。
我想知道是否会有任何重大更改来允许 typeof(variable)
。
例如,使用以下代码:
class Animal { /* ... */ }
class Goat : Animal { /* ... */ }
/* ... */
var g = new Goat();
Animal a = g;
Console.WriteLine(typeof(Goat));
Console.WriteLine(typeof(Animal));
Console.WriteLine(g.GetType());
Console.WriteLine(a.GetType());
您会得到类似以下内容的内容:
山羊
动物
山羊
山羊
为什么不能这样做:
Console.WriteLine(typeof(g));
Console.WriteLine(typeof(a));
山羊
动物
我粗略地浏览了一下规范,没有发现任何冲突。我认为这会澄清“为什么是这种类型?”的问题。使用 typeof
运算符时。
我知道编译器是有能力的。使用扩展方法的实现实际上很简单:
public static Type TypeOf<T>(this T variable)
{
return typeof(T);
}
但这感觉很脏,滥用了编译器的类型推断。
On a few separate occasions, I have tried to coax the declared type out of a variable, relatively far from its declaration, only to find out that typeof(T)
only works on type names.
I was wondering if there would be any breaking changes to allow typeof(variable)
as well.
For example, with this code:
class Animal { /* ... */ }
class Goat : Animal { /* ... */ }
/* ... */
var g = new Goat();
Animal a = g;
Console.WriteLine(typeof(Goat));
Console.WriteLine(typeof(Animal));
Console.WriteLine(g.GetType());
Console.WriteLine(a.GetType());
You get something like:
Goat
Animal
Goat
Goat
Why is it not possible to do this:
Console.WriteLine(typeof(g));
Console.WriteLine(typeof(a));
Goat
Animal
I have given the spec a cursory glance, and can't find any conflict. I think that it would clear up the question 'Why this type?' when using the typeof
operator.
I know that the compiler is capable, here. An implementation using extension methods is actually trivial:
public static Type TypeOf<T>(this T variable)
{
return typeof(T);
}
But that feels dirty, abusing the type-inference of the compiler.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您只是想获取某物的类型,您可以将
其称为“应该给予您想要的行为”。
If you are simply trying to get the type of something, you can just call
it should give to the behavior you want.
您似乎在这里问两个不同的问题,第一个是为什么没有运算符来查找声明的变量类型,另一个是为什么 typeof(o) 不能等于 o.GetType()。
对于第一个,原因是因为它没有任何用途,根据定义,变量的声明类型在编译时总是已知的。为其添加一个运算符不会增加任何价值。
另一方面,问题是使用 typeof(instance) 会导致解析问题。正如 Jason 上面提到的,考虑一下:
t 是什么?如果您将 t 视为 typeof(string),那么您只需向语言添加大量重大更改。想象一下目前假设 t 是动物的所有代码,这目前是正确的。
但是,如果您将 t 视为 typeof(Animal),那么您的代码就会非常脆弱。想象一下这样的情况:当您编写代码时没有 Animal 类,但一年后有人在您导入的某个命名空间中添加了 Animal 类。您的代码将会中断,因为解析规则现在将使用 Animal 类型而不是局部变量。
You seem to be asking two different questions here, the first being why is there no operator for finding the declared variable type, and the other asking why can't typeof(o) be the equivalent of o.GetType().
For the first, the reason is because it serves no purpose, the declared type of a variable is by definition always known at compile time. Adding an operator for it would add no value.
For the other, the problem is that using typeof(instance) causes problems with resolution. As Jason mentioned above, consider:
What is t? If you treat t as typeof(string), then you just adding massive breaking changes to the language. Imagine all the code out there that currently assumes t is an Animal, which is currently correct.
If you treat t as typeof(Animal), though, then your code is incredibly brittle. Imagine the situation where there was no Animal class when you wrote the code, but a year later somebody added an Animal class in some namespace that you imported. Your code would break because the resolution rules would now use the Animal type rather than the local variable.
我认为这里的问题是 .GetType() 比 typeof() 更旧。在 C# 中曾经有一天,你需要做一些事情
才能获取 String 类型(例如),直到 typeof() 诞生。我认为如果这个概念是原始语言设计的一部分,那么它确实可能像你所描述的那样工作。由于 typeof() 对该语言的介绍较晚,因此设计者必须做出选择:废弃/弃用/删除 .GetType() (并在此过程中使它的许多用途过时),使 typeof()与 GetType() 功能重叠(这就是您所要求的),或者使 typeof() 的用法不与 GetType() 重叠。我认为 C# 人们只是选择不让功能重叠(以保持事情简单明了),因此 typeof() 受到今天的限制。
I think the problem here is that .GetType() is older than typeof(). There used to be a day in C# where you needed to do
in order to get the String type (for example), until typeof() was born. I think if the concept had been part of the original language design, then indeed it might work as you describe. Due to typeof() being a late introduction to the language, then the designers had to make a choice: Obsolete/deprecate/remove .GetType() (and in the process make many, many uses of it obsolete), make typeof() overlap in functionality with GetType() (which is what you are asking), or make typeof()'s usage not overlap with GetType(). I think the C# people simply chose not to make the functionality overlap (to keep things simple and clear), and so typeof() was restricted in the way it is today.
假设允许:
Suppose it's allowed: