0

I'm using Microsoft.Extensions.Caching.Abstractions package in my solution. This package contains IDistributedCache interface. There is also defined an extension method with following signature: public static void Set(this IDistributedCache cache, string key, byte[] value)

In my project I've created the generic Set<> extension method that accepts any class instance, serializes it and stores as a byte[]. Unfortunately it doesn't work and causes infinite recursion:

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

I've also created a similar interface and two extension methods like this:

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!
    }
}

And .... it works fine! No recursive calls, no infinite loop. What's going on here? What is the difference between my IDistributedCache and IMyDistributedCache? Why te second example works? Thanks in advance.

rkamx
  • 1

1 Answers1

0

is because in your second example you have a method (same name = set) with a fully qualified type for value parameter (byte array). Compiler searches the signature of methods with best type match. If the method has a generic type, it has a priority 2.

see: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/generic-methods

if you change your example to follow, it will also end up in an infinite loop:

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
    }
}
Stefan
  • 21
  • 1