首页 > 解决方案 > 编译器匹配 where 子句排除它的扩展

问题描述

给定以下代码:

using System;
using Microsoft.Extensions.Logging;

namespace CompileError
{
    public interface IMessage
    {
        string UniqueId { get; }
    }

    public class Message : IMessage
    {
        public Message(string uniqueId)
        {
            this.UniqueId = uniqueId;
        }

        public string UniqueId { get; }
    }

    public static partial class IMessageExtensions
    {
        public static void LogInformation<TMessage>(this TMessage message, string information)
            where TMessage : IMessage
        {
            Console.WriteLine($"[{message.UniqueId}] {information}");
        }        
    }

    public static partial class ILoggerExtensions
    {
        public static void LogMessage<TMessage>(this ILogger logger, TMessage message)
            where TMessage : IMessage
        {
            // This line does not compile
            logger.LogInformation($"[{message.UniqueId}]");
            // But this one does
            logger.LogInformation($"[{message.UniqueId}]", 42);
            // At least, there's a workaround:
            LoggerExtensions.LogInformation(logger, $"[{message.UniqueId}]");
        }
    }
}

编译器在第一次调用LogInformationin时失败LogMessage,因为它认为我正在调用TMessage.LogInformation上面定义的调用,而不是LoggerExtensions.LogInformation从 MS 包调用。

我认为该where子句足以告诉编译器不要使用此扩展。显然,有一些解决方法,如图所示。我还可以确保它们不共享命名空间,并且从 中看不到错误LogInformation的命名空间LogMessage,但我很惊讶 C# 编译器无法解决这个问题。漏洞?

标签: c#.net-coreextension-methods

解决方案


推荐阅读