C # General Delegate

I am trying to figure out how to make a generic delegate returning a generic value. My first non-general scenario looks like this.

    delegate int FirstDelegate(int i);
    static FirstDelegate method;

    static void Main(string[] args)
    {
        method = ReturnInt;
        int i = method(3);
    }

    static int ReturnInt(int i)
    {
        return i;
    }

There is no problem. Everything is working fine. However, when I do this, common things get out of hand.

    delegate T FirstDelegate<T>(T i);
    static FirstDelegate<T> method; <--

Already here he begins to complain about the type or namespace, etc. etc. not found. Anyone have any ideas how to make this work?

Edit: My real goal is that I have a cache that can contain many different cache objects. And now I need a single method that is common, so I can get all the objects through this one. I could make it return an object or base layer, but then I still have to throw every object in all of its use.

Example of a dog / cat Non-native parts work .. generic .. not much

class Program
{
    static void Main(string[] args)
    {
        //Clientside
        Cache.method = GetAnimalOnClient;

        //not working
        Cache.methodGeneric = GetAnimalOnClientGeneric;

        var cat = Cache.GetCachedObj(AnimalType.Cat);
        var dog = Cache.GetCachedObj(AnimalType.Dog);

        //Want do
        vad dog = Cache.GetCachedObj<Dog>();
    }

    private static Animal GetAnimalOnClient(AnimalType type)
    {
        if (type == AnimalType.Dog)
            return Cache._Dogs.First();
        else
            return Cache._Cats.First();
    }

    /// <summary>
    /// This is the one I want to use
    /// </summary>
    private static T GetAnimalOnClientGeneric<T>() where T: Animal
    {
        if (typeof(T) == typeof(Cat))
            return Cache._Cats.First() as T;
        return Cache._Dogs.First() as T;
    }
}

public enum AnimalType
{
    Dog,
    Cat
}

public static class Cache
{
    delegate Animal GetCacheObjectDelegate(AnimalType type);
    public static GetCacheObjectDelegate method;

    delegate Animal GetCacheObjectDelegate<T>() where T : Animal;
    public static GetCacheObjectDelegate<T> methodGeneric; //<--Complains here

    public static List<Dog> _Dogs = new List<Dog>();
    public static List<Cat> _Cats = new List<Cat>();

    public static Animal GetCachedObj(AnimalType type)
    {
        return method(type);
    }

    public static T GetCachedObj<T>() where T: Animal
    {
        return methodGeneric<T>(); //NOPE
    }
}

public class Animal
{

}

public class Dog : Animal
{

}

public class Cat : Animal
{

}
+4
5

.

public static class Cache
{
    private static List<Dog> _dogs = new List<Dog>();
    private static List<Cat> _cats = new List<Cat>();

    public static TAnimal GetCachedObj<TAnimal>() where T: Animal
    {
        if(TAnimal == typeof(Dog))
           return (TAnimal) _dogs.First();
        else if (TAnimal == typeof(Cat))
           return (TAnimal) _cats.First();
        else throw new InvalidOperationException("Invalid generic type argument");
    }
}

: .

LSP , T (, Cat) Animal, Animal T - .

. , , Giraffe. , GetCachedObj<Giraffe>, ! Animal, LSP !

public class Cache<T> where T: Animal
{
    private static List<T> _animals = new List<T>();

    public T GetCachedObj()
    {
        return _animals.First();
    }
}

var dogsCache = new Cache<Dog>();
Dog dog = dogsCache.GetCachedObj();

var catsCache = new Cache<Cat>();
Cat cat = catsCache.GetCachedObj();

.

. , Cache . Singleton, ( ) Injection Dependency ( , Castle Windsor), .


generic ( @Sean), .

public class MyClass<T>
{
    public FirstDelegate<T> Method(){...}
}

T unbound ( ), T , :

public FirstDelegate<T> Method<T>(){...}

, T . T MyClass (.. new MyClass<int>), List<T>.

+4

method:

static FirstDelegate<int> method;
+4

, :

public static T GetDefault<T>(T par)
    {
        return default(T);
    }

:

System.Drawing.Point p = new Point();
System.Drawing.Point defaultPoint = GetDefault(p);
0

, , -. , , . baseclass, .

, LINQ IEnumerable:

public class AnimalCache

    private readonly Animals as new HashSet(of Animal)

    public function Add(Animal as Animal) as AnimalCache
        Animals.Add(Animal)
        return me
    end function

    public function GetAnimals(of AnimalType as Animal) as IEnumerable(of AnimalType)
        return Animals.OfType(of AnimalType)
    end function
end class

:

dim Cache = new AnimalCache().
    Add(new Cat).Add(new Dog).Add(new Cat)

dim CachedCats = Cache.GetAnimals(of Cat)
dim CachedDogs = Cache.GetAnimals(of Dog)

, Giraffe , AnimalCache :

public class Giraffe 
    inherits Animal

end class

dim Cache = new AnimalCache().
    Add(new Cat).Add(new Dog).Add(new Giraffe)

dim CachedGiraffes = Cache.GetAnimals(of Giraffe)
0

You can declare a dictionary in the Cache class, use the type of the Animal class as the key, and List <Animal> as the value.

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    public static void Main(string[] args)
    {
        Cache.AddCacheObj<Dog>(new Dog());
        Cache.AddCacheObj<Cat>(new Cat());

        var cat = Cache.GetCachedObj<Dog>();
        Console.WriteLine("Cat: {0}", cat);

        var dog = Cache.GetCachedObj<Cat>();
        Console.WriteLine("Dog: {0}", dog);     
    }
}

public static class Cache
{
    static Dictionary<Type, List<Animal>> dict = new Dictionary<Type, List<Animal>>();

    public static T GetCachedObj<T>() where T: Animal
    {
        List<Animal> list;
        if (dict.TryGetValue(typeof(T), out list))
        {
            return list.FirstOrDefault() as T;
        }
        return null;
    }

    public static void AddCacheObj<T>(T obj) where T: Animal
    {
        List<Animal> list;
        if (!dict.TryGetValue(typeof(T), out list))
        {
            list = new List<Animal>();
            dict[typeof(T)] = list;
        }
        list.Add(obj);
    }
}

public class Animal
{
    public override string ToString()
    {
        return "This is a " + this.GetType().ToString();
    }
}

public class Dog : Animal
{

}

public class Cat : Animal
{

}

Exit:

Cat: This is a Dog
Dog: This is a Cat

You can check the demo code here: https://dotnetfiddle.net/FYkCw7

0
source

Source: https://habr.com/ru/post/1527895/


All Articles