为什么即使类标记为“过时”,此代码也能编译而没有错误
本文关键字:代码 编译 有错误 记为 过时 为什么 | 更新日期: 2023-09-27 17:56:07
这是Visual Studio 2008。 显然与扩展的静态类有关。
public class Dummy
{
public readonly int x;
public Dummy(int x)
{
this.x = x;
}
public override string ToString()
{
return x.ToString();
}
}
[Obsolete("Do Not Use", true)]
public static class Extensions
{
public static int Squared(this Dummy Dummy)
{
return Dummy.x * Dummy.x;
}
}
class Program
{
static void Main(string[] args)
{
var d = new Dummy(42);
Console.WriteLine(String.Format("{0}^2={1}", d, d.Squared()));
}
}
这在VS2010中也是如此。看起来像一个错误。 我会把它输入到数据库中。
您可以通过将属性放在实际方法上来解决该错误。
感谢您的报告!
调用过时的函数是警告,而不是错误,除非您将编译器设置更改为在出现警告时停止 - 使警告的行为类似于错误。
通常,除非我的代码中存在其他"真实"错误,否则我看不到这些警告。
另请注意,在您的特定情况下,您将类标记为过时 - 而不是方法。这可能很重要。
我认为您发现了一个编译器错误:
尽管扩展方法将被编译为静态方法用法,但编译器似乎不会检查它,因为在编译时它以实例方法调用的格式存在。
原因就在这里。如果我声明第二种方法:
[Obsolete("Do Not Use", true)]
public static class Extensions
{
public static int Squared(this Dummy Dummy)
{
return Dummy.x * Dummy.x;
}
public static int Squared2(Dummy Dummy)
{
return Dummy.x * Dummy.x;
}
}
现在它在第三行而不是第二行抱怨:
class Program
{
static void Main(string[] args)
{
var d = new Dummy(42);
Console.WriteLine(String.Format("{0}^2={1}", d, d.Squared())); // Fine!?
Console.WriteLine(String.Format("{0}^2={1}", d, Extensions.Squared2(d))); // COmplains as expected
}
}
因为它是一个扩展方法,所以你不直接访问静态类,编译器会生成该代码。
相反,如果显式访问Squared
方法,则会收到编译时错误。
Extensions.Squared(d)
但是,由于这是一个扩展方法,因此仅隐式调用该方法,因此需要将属性应用于方法本身。
public static class Extensions
{
[Obsolete("Do Not Use", true)]
public static int Squared(this Dummy Dummy)
{
return Dummy.x * Dummy.x;
}
}
另一方面,完全删除(或重命名)类将达到相同的目的 - 在这种情况下,您肯定会收到编译时错误。 :)
编辑
您可以在此处提交错误报告Microsoft。 这似乎是应该由编译器处理的行为。
我认为您需要将属性放在 Squared 上,而不是类上。