2013-03-21 3 views
1

я не могу понять, почему следующий код не компилируется:Почему следующий код не компилируется?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace ConsoleApplication1 { 
    public interface ITestCondition<T> { 
    } 

    public class TestConditionBase<T>: ITestCondition<T> { 
    } 

    public class TestCondition<T>: TestConditionBase<T> { 
    } 

    public static class TestConditionExtension { 
     public static V Foo<V, T>(this V condition) where V: ITestCondition<T> { 
      return condition; 
     } 
    } 

    class Program { 
     static void Main(string[] args) { 
      new TestCondition<int>().Foo(); 
     } 
    } 
} 

Он говорит, что не может найти «Foo». Но он отлично работает без общего типа.

+1

Составлено на меня ': /' –

+0

@ SonerGönül .Net C# 4.5 – rudimenter

ответ

4

V может быть выведено, но T не может, и поэтому вызов Foo должен завершиться неудачей.

Почему T не может быть выведен?

При выполнении вывода типа метода C# никогда не делает вывод типа из ограничения. Выводы сделаны путем изучения взаимосвязи между аргументами и их соответствующими формальными параметрами . Только после завершения мы проверяем, что ограничение выполнено.

+0

Вы правы. Когда я использую T как аргумент метода и вызываю их метод, например, с int, он работает. Благодарю. – rudimenter

5

Компилятор не может вывести типы. Укажите их в явном виде:

new TestCondition<int>().Foo<TestCondition<int>, int>(); 
3

Я думаю, что вы ищете это в качестве метода расширения:

public static class TestConditionExtension 
{ 
    public static ITestCondition<T> Foo<T>(this ITestCondition<T> condition) 
    { 
     return condition; 
    } 
} 

Поскольку V всегда является ITestCondition, там действительно нет причин, чтобы сделать его более универсальным, чем это.

Быстрое эмпирическое правило, которое я использую, когда я рассматриваю использование общего аргумента: «Неважно, какой он тип». В этом случае конкретный тип J не имеет значения, как раз для родительского типа. Поэтому не используйте общий тип, просто используйте родительский тип. Надеюсь, это имеет смысл.

+0

Существует причина. Если вы хотите вернуть более конкретный тип, то только базовый интерфейс. Важно для свободного интерфейса. – rudimenter

+0

Ах, я вижу, поэтому вы хотите вернуть тот же тип, что и тип ввода. Тогда @ ken2k совершенно прав. – IdeaHat

Смежные вопросы