Ich war heute überrascht wie die Methodenauflösung funktioniert.C# Methodenauflösung mit generischer und typischer Inferenz
Hier ist der Code als exemple:
class Program
{
static class Mapper<TSource, TTarget>
{
public static void Map<TMember>(Expression<Func<TSource, TMember>> source, Expression<Func<TTarget, TMember>> target)
{
Console.WriteLine("A");
}
public static void Map<TMember, TSourceCollection>(Expression<Func<TSource, TSourceCollection>> source, Expression<Func<TTarget, TMember[]>> target)
where TSourceCollection : IEnumerable<TMember>
{
Console.WriteLine("B");
}
}
class A
{
public byte[] prop { get; set; }
}
class B
{
public byte[] prop { get; set; }
}
static void Main(string[] args)
{
Mapper<A, B>.Map(x => x.prop, x => x.prop);
}
}
Wie Sie sehen die Methode Karte zwei Überlastungen hat, ein, wenn die Art der Eigenschaften sind die gleichen, und man, wenn die Quelleigenschaft eine zählbare ist und die rechte Eigenschaft ist ein Array.
Dann wenn ich die Methode mit einem Array auf beiden Seiten aufrufen, ruft es die zweite Überladung, aber da die Typen genau gleich sind, erwartete ich die erste Überladung aufgerufen werden.
Ich dachte, die erste Überladung hätte eine bessere Bewertung, weil sie von weniger generischen Argumenten abhängt als die zweite, und sie passt besser zu den Typen der Argumente, die ich an die Methode übergebe.
Kann jemand erklären, warum der Compiler wählt, die zweite Überladung anstelle der ersten zu nennen?
Danke.
Sie nennen den Mapper mit einer Klasse A und B, die keine Arrays sind. Beide haben eine Eigenschaft, die ein Byte-Array ist, aber sie sind nicht vom selben Typ. – Glubus
Ändern Sie Byte [] in int und die erste wird verwendet. Ich denke also, weil ein Byte-Array ein IEnumerable ist. – user743414
Danke aber die Auflösung sollte auf TMember, nicht TSource oder TTarget auftreten. Die TSource und TTarget sind von Natur aus unterschiedlich. –