通用扩展方法调用非通用重载,并导致无限递归

问题描述 投票:0回答:1

我在解决方案中使用Microsoft.Extensions.Caching.Abstractions包。该软件包包含IDistributedCache接口。还定义了具有以下签名的扩展方法:public static void Set(this IDistributedCache cache, string key, byte[] value)

在我的项目中,我创建了通用的Set <>扩展方法,该方法接受任何类实例,对其进行序列化并存储为字节[]。不幸的是,它不起作用并导致无限递归:

public static void Set<T>(this IDistributedCache cache, string key, T value) where T : class
{
    byte[] byteArray = value.ToByteArray();
    cache.Set(key, byteArray); // recursion call here, my generic method Set<byte[]> is called here instead of the non-generic version from Microsoft.Extensions.Caching.Abstractions
    // temporary workaround is to call: 
    // Microsoft.Extensions.Caching.Distributed.DistributedCacheExtensions.Set(cache, key, byteArray);
}

我还创建了一个类似的界面和两个扩展方法,如下所示:

public interface IMyDistributedCache
{

}

public static class MyDistributedCacheExtensions
{
    public static void Set(this IMyDistributedCache cache, string key, byte[] value)
    {

    }
}
public static class MySecondDistributedCacheExtensions
{
    public static void Set<T>(this IMyDistributedCache cache, string key, T value) where T : class
    {
        byte[] byteArray = value.ToByteArray();
        cache.Set(key, byteArray); // works fine! no recursive calls!
    }
}

而且....它工作正常!没有递归调用,没有无限循环。这里发生了什么?我的IDistributedCache和IMyDistributedCache有什么区别?为什么第二个示例有效?预先感谢。

c# .net extension-methods
1个回答
0
投票

是因为在第二个示例中,您有一个方法(同名=设置),其值参数(字节数组)具有完全限定的类型。编译器搜索具有最佳类型匹配的方法的签名。如果该方法具有泛型类型,则优先级为2。

请参阅:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/generic-methods

如果您更改示例以使其遵循,它也会以无限循环结尾:

public interface IMyDistributedCache
{

}

public static class MyDistributedCacheExtensions
{
    public static void Set(this IMyDistributedCache cache, string key, byte[] value)
    {

    }
}
public static class MySecondDistributedCacheExtensions
{
    public static void Set<T>(this IMyDistributedCache cache, string key, T value) where T : class
    {
        byte[] byteArray = value.ToByteArray();
        cache.Set<byte[]>(key, byteArray); //<<< endless loop
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.