为什么编译器发现这个含糊不清?

时间:2009-11-03 14:50:32

标签: c# compiler-construction intellisense

在我的基类中,我有一个泛型方法(理想情况下这是一个属性,但你不能拥有泛型属性)和一个非泛型属性,两者都有相同的名称:

protected static T CurrentUserId<T>()
{
    ...
}

protected static string CurrentUserId
{
    get
    {
        ...
    }
}

然而,当我来使用它们中的任何一个时,intellisense报告它们之间的歧义。当然,base.CurrentUserId(没有parethesese)为我想要调用非泛型属性的编译器提供了足够的线索?

有谁知道为什么编译器会遇到这种情况?提前谢谢。

3 个答案:

答案 0 :(得分:9)

括号不提供足够的信息,因为您并不总是使用它们。这就是为什么这不起作用的原因:

delegate T MyDelegate<T>();

new MyDelegate(myClass.CurrentUserId)

//are we talking about the method or the property?

答案 1 :(得分:5)

如果你遗漏了泛型,比如:

public int Value { get;  set; }

public int Value()
{
    return 1;
}

您还会收到错误:类型...已包含值

的定义

我可以想到一个存在明显冲突的案例:

MyDelegate foo = new MyDelegate(Value);

答案 2 :(得分:4)

Paul关于“将泛型引入混合似乎完全掩盖这个更基本的问题”的评论似乎是正确的。

我相信你的问题与泛型有关,而与如何适当地重载方法有关(我可能在这方面错了,但这是我从查找方法重载中收集的)。我甚至不确定属性是否可以通过具有相同名称的方法重载,但无论如何,让我们快速查看方法重载,这仍然应该说明为什么代码不起作用。

如果方法的签名不同,您可以重载同名方法(在您的情况下,名称为CurrentUserId)。签名包含以下四条信息:

  • 方法的名称
  • 参数数量
  • 参数的数据类型和顺序
  • 参数修饰符

根据Daniel Solis的 Illustrated C#2008

  

“返回类型不是签名的一部分 - 尽管认为它是一个常见的错误。”

让我们看一下你的财产和方法,看看他们是否可以根据上面提供的四条信息签署相同的签名:

  • 方法的名称是否相同?是的,CurrentUserId
  • 参数个数是否相同?是的,0。
  • 参数的数据类型和顺序是否相同?两者都没有参数,所以是的。
  • 参数修饰符是否相同?同样,属性和方法都没有参数,所以是的,它们是相同的。

当您从等式中删除参数时,我们唯一唯一标识该类型的是其名称。此外,由于方法(或属性)的返回类型不是其签名的一部分,因此一种类型是字符串而另一种类型是通用类型并不重要。无论哪种方式,两者都具有相同的签名(因为它们的名称相同且没有参数),编译器将无法正确区分它们。

所有这一切,我不确定这是否完全回答了你的问题(或者即使我正确地解决了这个问题......我很乐意欢迎在评论中进行更正以促进我个人的理解)。但是,我发现通过 first 正确理解重载来解决问题非常有助于解决编译器如何处理代码的整体问题。

我希望这会有所帮助。