C#中的子类和泛型

时间:2016-10-14 17:00:20

标签: c#

我想继承大量的类,以便它们都包含一组相同的属性。为避免重复,这样做的正确方法是什么?我想过使用泛型,如:

public class SuperT<T> : T
{
    //the same set of properties
}

但是编译器说

  

无法从'T'派生,因为它是一个类型参数

编辑:我试图在第三方程序集中继承某些类,因此我不能使用基类。

例如,类型是“Image”,“Label”,“Button”等,我想将它们全部子类化为包含像“Radius”这样的属性。 (因此我将在XAML中使用SuperImage元素,当我从XAML设置它的Radius属性时,我将能够运行某些逻辑。)

我刚想到的另一种方法是使用T4模板。我想知道是否有办法用泛型做这个而不诉诸模板?我无法理解为什么编译器会拒绝它。

5 个答案:

答案 0 :(得分:1)

我不认为仿制药与此有任何关系,但遗传可能就是你要找的东西。

有两种类型的继承可用于子类化,而扩展方法可用于“超类”......排序。

  1. Is-A继承
  2. Has-A继承
  3. 要简单地向一堆第三方对象添加类似的方法,您将使用扩展方法。
  4. Is-A继承

    如果您有类似的方法实现,请使用基类。

    public abstract class BaseFoo {
    
        public void Bar() {
             // actual code
        }
    }
    
    public class Foo : BaseFoo
    {
    }
    
    var foo = new Foo();
    foo.Bar();
    

    如果需要在每个类上实现相同的方法,请使用接口。

    public interface IFoo {
        void Bar();
    }
    
    public class Foo : IFoo {
        public override void Bar(){
            // bar implementation
        }
    }
    
    var foo = new Foo();
    foo.Bar();
    

    也允许组合这两者,但是你只能在基类上继承,在那里你可以继承多个接口。

    Has-A继承

    这对依赖注入特别有用,但它只是你有另一个类的实例可以使用的概念。它本质上是一个你可以使用的包装类。

    public class Foo {
        private readonly ThirdPartyFoo _tpFoo;
        void Foo(ThirdPartyFoo tpFoo) {
            _tpFoo = tpFoo;
        }
    
        public void Bar(){
            // now I can do something with _tpFoo;
           _tpFoo.Bar(); 
        }
    }
    
    var tpFoo = new ThirdPartyFoo();
    var foo = new Foo(tpFoo);
    foo.Bar(); // invokes the underlying tpFoo
    

    最后,如果您只需要向现有类添加方法,则可以创建扩展方法。

    public static class ViewExtensions() 
    {
        // this assumes your Image, Button, Label all inherit from View.
        public static Whatever Radius(this View view) {
            // do your radius work.
        }
    
    }
    

答案 1 :(得分:1)

如果这些类都共享一个公共基类或公共接口,则可以编写扩展方法。

public static class ShapeExetnsionsExtLib
{
    public static double Radius(this ShapeBase shape){
        return /*calculate radious*/;
    }
}

来自评论

  

我试图在第三方程序集中继承一些类,所以我不能使用基类。

     

例如,类型是“Image”,“Label”,“Button”等,我想将它们全部子类化为包含“radius”之类的属性。

     

是的,他们共享共同的基类,但我不能添加任何新的基础类。

答案 2 :(得分:0)

只需使用基类:

public class Base
{
    public int Id { get; set; }
    public string Name { get; set; }
}

并从中继承:

public class A : Base
{

}

public class B : Base
{

}

答案 3 :(得分:0)

通常,您希望使用已发布的有关使用基类并从中继承的答案之一。但是,如果类位于第三方库中并标记为sealed,那么您将需要创建一个包装类以用作基类。

(请注意,此选项是一种解决方法,并不会真正从第三方类继承,因此如果没有自由使用,则无法访问该类中标记为protected的内容反射。)

// The sealed class within another library
public sealed ThirdPartyClass
{
    public ThirdPartyClass(int i) { }

    public int SomeProperty { get; set; }

    public int SomeMethod(string val) { return 0; }

    public static void SomeStaticMethod() { }
}

// The wrapper class to use as a pseudo base class for ThirdPartyClass
public class BaseClass
{
    private ThirdPartyClass _obj;

    public BaseClass(int i) { _obj = new ThirdPartyClass(i); }

    public int SomeProperty
    {
        get { return _obj.SomeProperty; }
        set { _obj.SomeProperty = value; }
    }

    public int SomeMethod(string val) { return _obj.SomeMethod(val); }

    public static SomeStaticMethod() { ThirdPartyClass.SomeStaticMethod(); }
}

// The child class that inherits from the "base" BaseClass
public class ChildClass : BaseClass
{

}

答案 4 :(得分:0)

首先,这可能是一个逻辑问题。如果您要扩展密封课程怎么办?还是Int32类?的代表

无论如何,我建议的方法是创建一个接口并实现子类中所需的所有功能。