如何处理c#中的基类构造函数

本文关键字:基类 构造函数 何处理 处理 | 更新日期: 2023-09-27 18:12:54

我有一个扩展基类的类。基类更加泛型,因此需要更多的参数。派生类是基类的特定类型,因此只需要基类在其构造函数中需要的两个参数中的一个(派生类可以向基类提供第二个参数,但需要先进行一些处理)。

是否有可能在派生类中有一个构造函数,然后调用基类的构造函数?

我知道如果直接传递参数,我可以使用: base(int a, int b),但我认为我不能这样做,因为我需要在调用基类构造函数之前处理第二个变量。

class Foo {
    private int c;
    public Foo(int a, int b) {
        c = a + b;
    }
}
class Bar : Foo {
    public Bar(int a, bool plusOrMinus) {
        if (plusOrMinus) {
            Foo(a, 5); // calling base class constructor- AFTER processing
        } else {
            Foo(a, -5); // calling base class constructor- AFTER processing
        }
    }
}

如何处理c#中的基类构造函数

一种方法是使用三元操作符

public Bar(int a, bool plusOrMinos) : base(a, plusOrMinus ? 5 : -5) {
  ...
}

对于更复杂的条件,应该切换到静态工厂方法

private Bar(int a, int b) : base(a, b) {
  ...
}
public static Bar Create(int a, bool plusOrMinus) {
  if (plusOrMinus) {
    return new Bar(a, 5);
  } else {
    return new Bar(a, -5);
  }
}

可以内联,不是吗?

public Bar(int a, bool plusOrMinus) : base(a, plusOrMinus ? 5 : -5) {
}
如果您需要做一些更复杂的事情,您可以将逻辑提取到静态方法中:
public Bar(int a, bool plusOrMinus) : base(a, GetValueFromPlusOrMinus(plusOrMinus)) {
}
public static int GetValueFromPlusOrMinus(bool plusOrMinus) 
{
    if (plusOrMinus)
        return 5;
    else
        return -5;
}

如果您可以编写一个静态函数来处理数据,则可以或多或少地做到这一点:

class Bar : Foo 
{
    public Bar(int a, bool plusOrMinus) : base(a, calc(plusOrMinus))
    {
    }
    private static calc(bool pom) : ...; return -5; }
}

我的建议是使用组合而不是继承。

不要让一堆子类(a, B, C)从基类(X)派生,而要让a, B, C包含一个可以调用的X的私有实例。

这样,你只在一个地方(X)拥有共享逻辑,并且你所有的类都可以使用它。

class Foo {
    private int c;
    public Foo(int a, int b) {
        c = a + b;
    }
}
class Bar {
    private Foo _base;
    public Bar(int a, bool plusOrMinus) {
        if (plusOrMinus) {
            _base = new Foo(a, 5);
        } else {
            _base = new Foo(a, -5);
        }
    }
}

这个方法怎么样?

class Foo
{
    private int c;
    public Foo(Builder builder)
    {
        c = builder.A ?? 0 + builder.B ?? 0;
    }
}
class Bar : Foo
{
    public Bar()
        : base(new Builder().WithA(2).WithB(3).WithPlusOrMinus(false))
    {
    }
}

public class Builder
{
    public int? A { get; private set; }
    public int? B { get; private set; }
    public bool? PlusOrMinus { get; private set; }
    public Builder WithA(int a)
    {
        A = a;
        return this;
    }
    public Builder WithB(int b)
    {
        B = b;
        return this;
    }
    public Builder WithPlusOrMinus(bool plusOrMinus)
    {
        if(!plusOrMinus)
        {
            B *= -1;
        }
        return this;
    }
}

我更喜欢在基类上创建一个受保护的Initialize(…),并在继承类的ctr的末尾调用它