2013-03-21 99 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(); 
     } 
    } 
} 

它說,它無法找到「富」。但它沒有泛型類型就可以很好地工作。

+1

編譯我':/' – 2013-03-21 15:49:24

+0

@SonerGönül.Net C#4.5 – rudimenter 2013-03-21 16:15:18

回答

4

可以推斷出V但T不能,因此對Foo的調用必須失敗。

爲什麼T不能被推斷?

執行方法類型推斷時C#從不從約束進行類型推斷。通過檢查參數與其對應的形式參數類型之間的關係來進行推論。推斷完成後只有我們檢查一下是否滿足約束條件。

+0

你說得對。當我使用T作爲方法參數,並用int調用它們的方法時,它可以工作。謝謝。 – rudimenter 2013-03-21 17:00:14

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 2013-03-21 16:16:23

+0

啊,我明白了,所以你想返回與輸入類型相同的類型。然後@ ken2k是完全正確的。 – IdeaHat 2013-03-21 16:28:34