2011-05-10 65 views
12

我試圖懶惰並在抽象基類而不是每個派生的具體類中實現演員操作符。我已經設法施展了一種方式,但我無法施展另一種方式。我想可能是不可能的,但要挑集體放棄以前那麼介意:在通用抽象類中實現一個演員操作符

public interface IValueType<T> 
{ 
    T Value{ get; set; } 
} 

public abstract class ValueType<T> : IValueType<T> { 
    public abstract T Value { get; set; } 
    public static explicit operator T(ValueType<T> vt) { 
     if(vt == null) 
      return default(T); 
     return vt.Value; 
    } 

    public static implicit operator ValueType<T>(T val) { 
     ValueType<T> vt = new ValueType<T>(); //<--- obviously this won't work as its abstract 
     vt.Value = val; 
     return vt; 
    } 
} 
+0

部分認爲你可以用反射做到這一點,但大部分我說,在派生類中做更有意義,因爲它是單個派生類的工作,知道如何從T到它,而不是T的工作他抽象類。 – 2011-05-10 11:53:11

+0

其實,我認爲即使使用反射也不能做到這一點,因爲它們是靜態方法,而我在想的是實例方法。 – 2011-05-10 11:57:30

+0

@Matt Ellen我同意最好在具體類中做,但我寧願寫一次方法,而不是將它複製到幾十個派生類中。 – 2011-05-10 12:03:10

回答

10

您需要引入另一種通用的參數來識別具體類型。

像..

public interface IValueType<T> 
{  
    T Value{ get; set; } 
} 

public abstract class ValueType<T,K> : 
    IValueType<T> where K : ValueType<T,K>,new() 
{  
    public abstract T Value { get; set; }  
    public static explicit operator T(ValueType<T,K> vt) 
    {   
     if(vt == null)    
      return default(T);   
     return vt.Value;  
    }  

    public static implicit operator ValueType<T,K>(T val) 
    {   
     K k = new K(); 
     k.Value = val; 
     return k;  
    } 
} 

創建您的具體類

public class Test : ValueType<int,Test> 
{ 
    public override int Value {get;set;} 
} 

然後我

var t = new Test(); 
t.Value = 99; 
int i = (int)t; 
Test t2 = (Test)6; 

Console.WriteLine(i); 
Console.WriteLine(t2); 
+0

我看到你仍然必須顯式地將一個'int'轉換爲'Test':'Test t2 =(Test)6;'。我想這是因爲我們不能實現'公共靜態隱式運算符K(T val){...}'而不會產生編譯時錯誤(CS0556)。 – 2011-05-14 09:07:06

+0

我想到了一個鏈接隱式運算符的解決方案,但被卡在那裏,請參閱:http://stackoverflow.com/questions/6001854/chaining-implicit-operators-in-generic-c-classes – 2011-05-14 12:34:48