C#/.NET:“typeof(variable)”是一种可能的语言功能吗?

发布于 2024-10-01 03:50:53 字数 913 浏览 12 评论 0原文

在一些单独的场合,我尝试将声明的类型从变量中导出,距离其声明相对较远,却发现 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

等风来 2024-10-08 03:50:54

如果您只是想获取某物的类型,您可以将

Type t1 = myObject.GetType();

其称为“应该给予您想要的行为”。

If you are simply trying to get the type of something, you can just call

Type t1 = myObject.GetType();

it should give to the behavior you want.

不念旧人 2024-10-08 03:50:54

您似乎在这里问两个不同的问题,第一个是为什么没有运算符来查找声明的变量类型,另一个是为什么 typeof(o) 不能等于 o.GetType()

对于第一个,原因是因为它没有任何用途,根据定义,变量的声明类型在编译时总是已知的。为其添加一个运算符不会增加任何价值。

另一方面,问题是使用 typeof(instance) 会导致解析问题。正如 Jason 上面提到的,考虑一下:

public class Animal {}
string Animal;
Type t = typeof(Animal);

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:

public class Animal {}
string Animal;
Type t = typeof(Animal);

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.

謌踐踏愛綪 2024-10-08 03:50:53

我认为这里的问题是 .GetType() 比 typeof() 更旧。在 C# 中曾经有一天,你需要做一些事情

"0".GetType()

才能获取 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

"0".GetType()

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.

清泪尽 2024-10-08 03:50:53

假设允许:

class Animal { }

string Animal;
Type t = typeof(Animal); // uh-oh!

Suppose it's allowed:

class Animal { }

string Animal;
Type t = typeof(Animal); // uh-oh!
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文