C# 泛型扩展方法调用非泛型重载并导致无限递归

C# 泛型扩展方法调用非泛型重载并导致无限递归,c#,.net,extension-methods,C#,.net,Extension Methods,我正在解决方案中使用Microsoft.Extensions.Caching.Abstractions包。此包包含IDistributedCache接口。还定义了具有以下签名的扩展方法: 公共静态无效集(此IDistributedCache缓存,字符串键,字节[]值) 在我的项目中,我创建了通用的Set扩展方法,它接受任何类实例,将其序列化并存储为字节[]。不幸的是,它不起作用并导致无限递归: public static void Set<T>(this IDistributedCa

我正在解决方案中使用Microsoft.Extensions.Caching.Abstractions包。此包包含IDistributedCache接口。还定义了具有以下签名的扩展方法:
公共静态无效集(此IDistributedCache缓存,字符串键,字节[]值)

在我的项目中,我创建了通用的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);
}
公共静态无效集(此IDistributedCache缓存,字符串键,T值),其中T:class
{
字节[]byteArray=value.ToByteArray();
cache.Set(key,byteArray);//这里调用递归,这里调用我的泛型方法集,而不是Microsoft.Extensions.Caching.Abstractions中的非泛型版本
//临时解决方法是调用:
//Microsoft.Extensions.Caching.Distributed.DistributedCacheExtensions.Set(缓存,键,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!
    }
}
公共接口IMyDistributedCache
{
}
公共静态类MyDistributedCacheExtensions
{
公共静态无效集(此IMyDistributedCache缓存,字符串键,字节[]值)
{
}
}
公共静态类MySecondDistributedCacheExtensions
{
公共静态无效集(此IMyDistributedCache缓存,字符串键,T值),其中T:class
{
字节[]byteArray=value.ToByteArray();
cache.Set(key,byteArray);//工作正常!无递归调用!
}
}
还有。。。。很好用!没有递归调用,没有无限循环。这是怎么回事?我的IDistributedCache和IMyDistributedCache之间有什么区别?为什么第二个例子有效?
提前感谢。

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

见:

如果您将示例更改为遵循,它也将以无限循环结束:

公共接口IMyDistributedCache
{
}
公共静态类MyDistributedCacheExtensions
{
公共静态无效集(此IMyDistributedCache缓存,字符串键,字节[]值)
{
}
}
公共静态类MySecondDistributedCacheExtensions
{
公共静态无效集(此IMyDistributedCache缓存,字符串键,T值),其中T:class
{
字节[]byteArray=value.ToByteArray();

cache.Set(key,byteArray);//我相信。你可以给它一个不同的名字。