编译器匹配where子句将其排除的扩展

时间:2018-05-04 13:18:36

标签: c# .net-core extension-methods

给出以下代码:

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}]");
        }
    }
}

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

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

0 个答案:

没有答案