【问题标题】:Why isn't this class reference ambiguous?为什么这个类引用不模棱两可?
【发布时间】:2021-03-25 12:38:09
【问题描述】:

我想知道为什么这种情况不会导致类型之间的模糊引用,一个是我们库中的类,一个是外部结构。考虑以下-

外部结构-

namespace External.Models
{
    public struct ProxyUser
    {
        public string Username { get; set; }
        public string Password { get; set; }
    }
}

我们班-

namespace MyApp.Configuration
{
    public class ProxyUser
    {
        public string Username { get; set; }
        public string Password { get; set; }
    }
}

然后调用代码近似-

using External.Models;

namespace MyApp.Configuration.Factories
{
    sealed class Factory
    {
        public async Task<T> BuildConfiguration<T>()
        {
            var proxy = new ProxyUser { Username = username, Password = password }; // I would expect this to be ambiguous, but it references out class
        }
    }
}

这是一个 NetStandard 2.0 库,如果这有所作为的话。如果我将我们的类设为结构,行为是相同的。为什么这不是模棱两可的?

EDIT - 类是密封的,如果这有什么不同的话......

回答

正如@Sinatr 提到的,它似乎与这个问题有关-https://stackoverflow.com/a/25437586/14872099

这是我观察到的不同行为的演示。

这将解析为我们的MyApp.Configuration.ProxyUser-

using External.Models;

namespace MyApp.Configuration.Factories
{
    sealed class Factory
    {
        public async Task<T> BuildConfiguration<T>()
        {
            var proxy = new ProxyUser { Username = username, Password = password }; // resolves to our class
        }
    }
}

这解析为外部结构-

namespace MyApp.Configuration.Factories
{
    using External.Models;

    sealed class Factory
    {
        public async Task<T> BuildConfiguration<T>()
        {
            var proxy = new ProxyUser { Username = username, Password = password }; // resolves to external struct
        }
    }
}

将我们的类移动到另一个命名空间会产生歧义-

using External.Models;
using MyApp.Configuration.Models; // moved our class to this namespace

namespace MyApp.Configuration.Factories
{
    sealed class Factory
    {
        public async Task<T> BuildConfiguration<T>()
        {
            var proxy = new ProxyUser { Username = username, Password = password }; // this is ambiguous
        }
    }
}

【问题讨论】:

  • 因为你在同一个命名空间组中。这两个类都在 MyApp.Configuration 命名空间内。
  • 它为什么知道我们的ProxyUser 类是有道理的,但不是为什么这不是模棱两可的。您是否知道任何记录歧义是如何确定的?
  • 你收到警告了吗?我找不到有关编译器如何解析最佳类型以匹配的主题。 AFAIR 本地程序集类型优先,参见例如this question.
  • 这很可能是由于usings,您只导入了一个命名空间,所以您不会收到错误。
  • 这个答案似乎是这样。由于using 语句在我们的命名空间之外,所以它在全局命名空间中,并且在我们的命名空间中处于次要地位。在我们的命名空间内移动 using 语句会导致它引用外部结构。 stackoverflow.com/a/25437586/14872099

标签: c# ambiguous


【解决方案1】:

内部命名空间(即namespace 括号内)优先于外部命名空间(即using 语句在namespace 块之前)。

注意:“内部”和“外部”在这里不是官方定义,我只是用它们来轻松区分它们。

由于嵌套,您的 namespace MyApp.Configuration.Factories 块本身也会查看任何直接祖先(MyApp.ConfigurationMyApp),但不会查看兄弟命名空间(例如 MyApp.Configuration.Services)。

当在内部命名空间中找到非歧义引用时,系统从不费心检查外部命名空间,因此不会发现冲突。只有在以下情况下才会遇到冲突:

  • 内部命名空间中有两个有效选项,例如MyApp.Configuration.ProxyUserMyApp.Configuration.Factories.ProxyUser
  • 在引用的外部命名空间中有两个有效选项,例如External.Models.ProxyUserAnother.Namespace.ProxyUser(假设在此文件中均使用 using 语句引用)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-01
    • 2023-03-24
    • 2013-06-21
    • 2016-03-08
    • 1970-01-01
    • 2018-05-28
    相关资源
    最近更新 更多