2011-04-16 62 views
1

我正在尋找一種方法來對待所有.Net數據類型一致,所以我可以創建下面的模式,其中任何類型實施IGetValue<out T>將投擲到IGetValue<object>。出於某種原因,如果T是struct,它不起作用,我不明白爲什麼。有沒有一種方法可以實現以下模式?我需要一個通用的類/接口任何.Net數據類型

public interface IGetValue<out T> 
{ 
    T Value 
    { 
     get; 
    } 
} 

public class GetValue<T> : IGetValue<T> 
{ 
    public GetValue(T value) 
    { 
     _value = value; 
    } 

    private T _value; 
    public T Value 
    { 
     get { return _value; } 
    } 
} 


class Program 
{ 
    static void Main(string[] args) 
    { 
     IGetValue<string> GetString = new GetValue<string>("Hello"); 
     IGetValue<int> GetInt = new GetValue<int>(21); 

     //This works!!! 
     if (GetString is IGetValue<object>) 
     { 
      Console.WriteLine("GetValue<string> is an IGetValue<object>"); 
     } 
     else 
     { 
      Console.WriteLine("GetValue<string> is not an IGetValue<object>"); 
     } 

     //This doesn't work!!! Why???? 
     if (GetInt is IGetValue<object>) 
     { 
      Console.WriteLine("GetValue<int> is an IGetValue<object>"); 
     } 
     else 
     { 
      Console.WriteLine("GetValue<int> is not an IGetValue<object>"); 
     } 

     Console.ReadKey(); 
    } 
} 

編輯:

我意識到發生了什麼,我想在這裏完成,似乎含糊其辭,但是這是一個更大的設計,其解釋是太冗長的一部分。我需要的是讓我的所有IGetValue<T>與一個名爲「Value」的屬性共享一個通用類型或接口,並返回一個object。爲什麼是冗長的部分。

+0

對象的價值是非常基本的概念。你想在這裏完成什麼? – 2011-04-16 10:41:48

回答

0

我最終通過創建非泛型IGetValue接口並在類中明確實現它來解決我的直接需求。這裏的解決方案:

public interface IGetValue 
{ 
    object Value 
    { 
     get; 
    } 
} 

public interface IGetValue<out T> 
{ 
    T Value 
    { 
     get; 
    } 
} 

public class GetValue<T> : IGetValue<T>, IGetValue 
{ 
    public GetValue(T value) 
    { 
     _value = value; 
    } 

    private T _value; 
    public T Value 
    { 
     get { return _value; } 
    } 

    object IGetValue.Value 
    { 
     get { return _value; } 
    } 
} 


class Program 
{ 
    static void Main(string[] args) 
    { 
     IGetValue<string> GetString = new GetValue<string>("Hello"); 
     IGetValue<int> GetInt = new GetValue<int>(21); 

     if (GetString is IGetValue) 
     { 
      Console.WriteLine("GetValue<string> is an IGetValue"); 
     } 
     else 
     { 
      Console.WriteLine("GetValue<string> is not an IGetValue"); 
     } 


     if (GetInt is IGetValue) 
     { 
      Console.WriteLine("GetValue<int> is an IGetValue"); 
     } 
     else 
     { 
      Console.WriteLine("GetValue<int> is not an IGetValue"); 
     } 

     Console.ReadKey(); 
    } 
} 
8

它不起作用,因爲通用方差不適用於值類型...他們有不同的表示,而與參考類型的方差可能發生,而CLR不必執行任何轉換。

因此,例如,您可以將IEnumerable<string>視爲IEnumerable<object>,但不能將IEnumerable<int>視爲IEnumerable<object>

+0

好的,謝謝你的解釋,但是有沒有辦法實現上面的模式。 – Verax 2011-04-16 10:22:30

+1

@Verax:不是書面的,沒有。 'Foo '永遠不會是'Foo '。儘管如此,很難確切地告訴你想要做什麼。 – 2011-04-16 10:52:44

+0

對於模糊性,我很抱歉。這是更大設計的一部分(正如您可能已經意識到的那樣),我將不得不解釋更大的設計,讓任何人都能完全理解我的目標。但是這對於這個論壇來說太冗長了。請回答我這個問題。 'int'繼承自'object'(最終),是嗎? 'object'是一個引用類型,是嗎?那麼爲什麼'int'需要被裝箱成爲一個引用類型,如果它首先從引用類型繼承? – Verax 2011-04-16 11:23:21

相關問題