2013-05-15 79 views
1

我正在接近一個問題,同時仍然對泛型及其正確的聲明/用法有一些無知。我得到了這個前提,但是泛型的一些缺陷仍然不見了。指定泛型類型作爲參數參數而不知道T

考慮下面的代碼(不編譯和包含的代碼異味):

public interface IUIConcern<out T> where T : IUIConcernExtension 
{ 

    string Name { get; } 
    Func<T> Extend(); 
} 

public class UIConcern 
{ 
    public static void Register<T>(string concernName, IUIConcern<T> uiConcern) where T : IUIConcernExtension 
    { 
     Concerns.Add(uiConcern); 
    } 

    public static List<IUIConcern<T>> Concerns{ 
     get { 
      // Logic... 
     } 
     set { 
      // Logic... 
     } 
    } 
} 

...我有幾個問題:

  • 我爲什麼要指定這部分public static void Register<T>(string concernName, IUIConcern<T> uiConcern) where T : IUIConcernExtension 當我已經約束了T的聲明public interface IUIConcern<out T> where T : IUIConcernExtension
  • 如何c我有一個財產,持有List<>我的IUIConcern<T>不知道T除了知道它會從IUIConcernExtension派生?

同樣,我知道這不會編譯,是不正確的,只是想看看我怎麼能認爲,可能有許多不同類型的IUIConcern<>元素的通用項目的列表。

謝謝!

回答

2

你需要有一個基本接口,例如:

public interface IUIConcern 
{ 
    string Name { get; } 
} 

public interface IUIConcern<out T> : IUIConcern where T : IUIConcernExtension 
{ 
    Func<T> Extern(); 
} 

你會如何定義ConcernsRegister將取決於你如何對待T。或者,如果您只處理知道T的實例,則可以使用Dictionary<Type, List<IUIConcern>>來保存任何內容,或者可能丟棄基本接口,並根據您的控制器代碼中需要使用object進行存儲。

2

問題不在於接口,但問題在於您的泛型實現使用靜態方法和屬性。

Guvante的回答是正確的,當你說你需要定義IUIConcernExtension時,但這當然是非常合乎邏輯的,所以即時通訊假設你剛剛省略了該部分,因爲這對你所面臨的問題無關緊要。

代碼的問題是,你已經創建了具有靜態方法和程序的一類,與一般定義在一流水平沒有規定,但在方法級,正因爲如此,的屬性,已經和方法不能認爲你總是相同的類型!

比方說,你打電話叫:

Register<string>("something", UIConcern<string>) 

但在此之前,你已經呼籲:

Register<Type>("something", UIConcern<Type>) 

怎麼可能編譯器可以讓你那?所以答案是在類級別定義泛型類型,所有的屬性和方法都是相同的。

還需要使用一個專用成員列表,因爲你做的一切靜態的,正確的代碼應該是:

interface IUIConcernExtension 
{ 
    string Name { get; } 
} 

public interface IUIConcern<out T> where T : IUIConcernExtension 
{ 
    Func<T> Extend(); 
} 

public class UIConcern<T> where T : IUIConcernExtension 
{ 
    private static List<IUIConcern<T>> _Concerns = new List<IUIConcern<T>>(); 

    public static void Register(string concernName, IUIConcern<T> uiConcern) 
    { 
     Concerns.Add(uiConcern); 
    } 

    public static List<IUIConcern<T>> Concerns 
    { 
     get { return _Concerns; } 
     set { _Concerns = value; } 
    } 
}