У меня есть следующий класс расширений:
public static class MatcherExtensions
{
public static ExecMatcher<T1, T2> Match<T1, T2>(this Tuple<T1, T2> item)
{
return new ExecMatcher<T1, T2>(item.Item1, item.Item2);
}
public static ExecMatcher<T1, T2> Match<T1, T2>(this ITupleMatchable<T1, T2> item)
{
var tuple = item.PropertiesToMatch;
return new ExecMatcher<T1, T2>(tuple.Item1, tuple.Item2);
}
public static ExecMatcher<T> Match<T>(this T item) { return new ExecMatcher<T>(item); }
}
Если я создаю кортеж и вызываю Match()
, он правильно использует первый метод расширения:
var tuple = Tuple.Create(1, "a");
tuple.Match().With(1, "a")... // compiles just fine.
Если я создаю int и вызываю Match()
, он правильно использует последний метод расширения:
var one = 1;
one.Match().With(1)... // compiles just fine.
Однако, если я создаю SomeClass
, который реализует ITupleMatchable<int, string>
и пытается и сопоставляется с ним, компилятор по-прежнему выбирает третий метод расширения, а не второй, несмотря на то, что последнее является более конкретным:
var obj = new SomeClass(1, "a");
obj.Match().With(1, "a")... // won't compile.
На основе Эрик Липперт отвечает на аналогичный вопрос, я работал над этим, добавив третий метод расширения в свой собственный класс в подкаталог, тем самым создав более длинный пространство имен и так далее "расстояние" между ним и вызывающим кодом, чем для версии, характерной для ITupleMatchable<T1, T2>
. Это похоже на взломать меня. Есть ли более простой способ разрешить это?