C#通用继承解决方法

时间:2011-05-22 20:03:29

标签: c# generics inheritance

示例:

我希望有几个专门的文本框,它们来自TextBox或RichTextBox,它们都来自TextBoxBase:

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); 
    }
}

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

不幸的是

class CommonFeatures<T> : T where T : TextBoxBase

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

有一个很好的解决方案吗?感谢。

2 个答案:

答案 0 :(得分: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,扩展方法也可能是一个很好的选择。

答案 1 :(得分: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 */);