繁体   English   中英

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

[英]Generic extension method calls non-generic overload and causes infinite recursion

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

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

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 有什么区别? 为什么第二个例子有效? 提前致谢。

是因为在您的第二个示例中,您有一个方法(同名 = 集),它具有值参数(字节数组)的完全限定类型。 编译器搜索具有最佳类型匹配的方法的签名。 如果该方法具有泛型类型,则它的优先级为 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
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM