我写什么而不是???????选择适当的过载?
using System;
using System.Collections.Generic;
namespace ConsoleApplication2
{
class A {}
class B : A {}
class C : A {}
class Program
{
static void Main(string[] args)
{
var l1 = new List<C>();
var l2 = new List<C>();
Comparer<C>(l1, l2, ???????);
}
void Compare(C a, C b) { }
void Compare(B a, B b) {}
void Compare<T>(IList<T> a, IList<T> b, Action<T,T> comparator)
{
for (int i = 0; i < a.Count; i++)
comparator(a[i], b[i]);
}
}
}
答案 0 :(得分:5)
您只需要使方法静态并修复方法名称。您甚至可以在对Compare
的初始调用中使用类型推断:
static void Main(string[] args)
{
var l1 = new List<C>();
var l2 = new List<C>();
Compare(l1, l2, Compare);
}
static void Compare(C a, C b) {}
static void Compare(B a, B b) {}
static void Compare<T>(IList<T> a, IList<T> b, Action<T,T> comparator)
{
for (int i = 0; i < a.Count; i++)
comparator(a[i], b[i]);
}
在这种情况下,没有歧义 - Compare(C, C)
是该组中唯一可转换为Action<C, C>
的方法。如果您使用Compare(A, A)
方法,则仍会选择更具体的方法。如果相反,你会有歧义:
static void Compare(A a, C b) {}
static void Compare(C a, A b) {}
但是,我会强烈建议在这种情况下,尽量避免超载。给方法赋予不同的名称 - 它会使它更容易阅读,并避免任何歧义。
答案 1 :(得分:0)
这取决于你想要对值做什么。如果您只是想传递一个代表,您可以执行以下操作
Comparer<C>(l1,l2, (left,right) => {});
在这种情况下,&lt; C&gt;部分实际上可以被取消。编译器将能够推断出参数。
我很好奇您为名为comparer的参数选择了Action<T,T>
。比较函数通常返回一个值,该值表示比较两个值的结果。 Action<T,T>
类型只返回void。它可能应该是
Func<T,T,int>
,这是比较功能的更标准签名