2011-05-22 63 views
2

例子:C#泛型继承的解决办法

我想有一个无论从文本框或RichTextBox中派生几个专门的文本框,这无论从Control派生:

class CommonFeatures<T> : T where T : TextBoxBase 
{ 
    // lots of features common to the TextBox and RichTextBox cases, like 
    protected override void OnTextChanged(TextChangedEventArgs e) 
    { 
     //using TextBoxBase properties/methods like SelectAll(); 
    } 
} 

然后

class SpecializedTB : CommonFeatures<TextBox> 
{ 
    // using properties/methods specific to TextBox 
    protected override void OnTextChanged(TextChangedEventArgs e) 
    { 
     ... base.OnTextChanged(e); 
    } 
} 

and

class SpecializedRTB : CommonFeatures<RichTextBox> 
{ 
    // using methods/properties specific to RichTextBox 
} 

不幸的是

class CommonFeatures<T> : T where T : TextBoxBase 

不编译(“无法从‘T’派生,因为它是一个类型参数”)。

有没有很好的解决方案呢?谢谢。

+0

它应该是类CommonFeatures 其中T:TextBoxBase – 2011-05-22 20:08:00

+0

@Tomas Voracek好这一点,类CommonFeatures :其中T:TextBoxBase因为CommonFeatures需要从它继承TextBoxBase的方法/属性,否则事情像OnTextChanged唐一类派生不存在。如果我直接从TextBoxBase继承,如何从RichTextBox或TextBox稍后添加属性/方法,而没有多重继承... – SemMike 2011-05-22 20:23:44

回答

6

C#泛型不从参数类型支持继承。

您真的需要CommonFeatures来自TextBoxBase吗?

一个简单的解决方法可能是使用聚合而不是继承。所以,你会有这样的事情:

public class CommonFeatures<T> where T : TextBoxBase 
{ 
    private T innerTextBox; 

    protected CommonFeatures<T>(T inner) 
    { 
     innerTextBox = inner; 
     innerTextBox.TextChanged += OnTextChanged; 
    } 

    public T InnerTextBox { get { return innerTextBox; } } 

    protected virtual void OnTextChanged(object sender, TextChangedEventArgs e) 
    { 
     ... do your stuff    
    } 
} 

像@oxilumin说,扩展方法也可以是一个伟大的选择,如果你并不真的需要CommonFeatures是一个TextBoxBase

+0

谢谢,我想我会做到这一点,我想你的意思是: 类SpecializedRTB:RichTextBox的 { \t私人CommonFeatures CF =新CommonFeatures (本); \t // SpecializedRTB的TextChanged事件已被捕获。 } 我怎么没想到:) – SemMike 2011-05-22 20:45:37

1

如果您的CommonFeature类没有它自己的条件 - 您可以使用扩展方法。

public static class TextBoxBaseExtensions 
{ 
    public static YourReturnType YourExtensionMethodName(this TextBoxBase textBoxBase, /*your parameters list*/) 
    { 
     // Method body. 
    } 
} 

然后你就可以用同样的方式与所有真正的类的方法,使用这种方法:

var textBox = new TextBox(); 
textBox.YourExtensionMethodName(/* your parameters list */); 
+0

谢谢,我会研究一下,但这样做是否允许受保护的override机制?我不得不加入 保护覆盖无效OnTextChanged(TextChangedEventArgs e){... base.ExtensionOnTextChanged(e); } 在这两个类中的手? – SemMike 2011-05-22 20:19:43

+0

@SemMike:不,用扩展方法只能访问公共类的成员。 – oxilumin 2011-05-22 20:27:39