J'ai le code C# suivant qui ne se comporte pas comme je le voudrais.Paramètre de type générique pour correspondre à tout ce qui est IEnumerable <T>
L'exigence est que tout ce qui implémente IEnumerable<T>
utilise la deuxième méthode qui imprime "2"
, mais tout le reste utilise la première méthode qui imprime "1"
.
Une démonstration naïve est ci-dessous. ICollection<int>
, IList<int>
, List<int>
et int[]
tout mettre en œuvre IEnumerable<T>
mais "1"
est imprimé à la place de "2"
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace Test
{
public class Program
{
public static void Main()
{
var parent = new Parent<Class>();
// OK: TProperty == int. Prints "1"
parent.Map(c => c.IntValue);
// OK: TProperty == int. Prints "2"
parent.Map(c => c.IEnumerableIntValue);
// Wrong: TProperty == ICollection<int>. Prints "1"
parent.Map(c => c.ICollectionIntValue);
// Wrong: TProperty == List<int>. Prints "1"
parent.Map(c => c.ListIntValue);
// Wrong: TProperty == int[]. Prints "1"
parent.Map(c => c.ArrayIntValue);
}
public class Class
{
public int IntValue { get; set; }
public IEnumerable<int> IEnumerableIntValue { get; set; }
public ICollection<int> ICollectionIntValue { get; set; }
public List<int> ListIntValue { get; set; }
public int[] ArrayIntValue { get; set; }
}
}
public class Parent<T>
{
public void Map<TProperty>(Expression<Func<T, TProperty>> expression)
{
Console.WriteLine("1");
}
public void Map<TProperty>(Expression<Func<T, IEnumerable<TProperty>>> expression)
{
Console.WriteLine("2");
}
}
}
J'ai essayé de changer la définition de
public void Map<TEnumerable, TElement>(Expression<Func<T, TEnumerable>> expression) where TEnumerable : IEnumerable<TElement>
{
Console.WriteLine("2");
}
mais cela nécessite des paramètres de type explicites à utiliser, ce qui est inacceptable:
parent.Map<int[], int>(c => c.ArrayIntValue);
Est-ce que quelqu'un a eu une idée sur la façon de réaliser cela en C# au moment de la compilation? Toutes les idées sont appréciées. Peut-être que les délégués contra/covariants pourraient travailler? J'ai essayé de me battre avec le compilateur C# mais je n'ai rien trouvé.
. En utilisant vos attentes, tous les appels devraient imprimer "2". –
Maintenant c'est un intéressant que je n'ai pas pensé à @rind –
Que diriez-vous de créer la méthode séparée pour IEnumerable: 'public void MapEnumerable (Expression >> expression)' –