我有两个构造函数,它们将值提供给只读字段。

public class Sample
{
    public Sample(string theIntAsString)
    {
        int i = int.Parse(theIntAsString);
        _intField = i;
    }

    public Sample(int theInt) => _intField = theInt;
    public int IntProperty    => _intField;

    private readonly int _intField;
}

一个构造函数直接接收值,另一个构造函数进行一些计算并获得值,然后设置字段。

现在问题来了:

我不想复制 设置代码。在这种情况下,只有一个 场地已经设置好了,当然还有可能 要大于1。 要使字段为只读,我需要 从构造函数中设置它们,那么 我不能将共享代码“提取”到 效用函数。 我不知道怎么叫 另一个构造函数。

什么好主意吗?


当前回答

以防你需要在调用另一个构造函数之前而不是之后运行一些东西。

public class Sample
{
    static int preprocess(string theIntAsString)
    {
        return preprocess(int.Parse(theIntAsString));
    }

    static int preprocess(int theIntNeedRounding)
    {
        return theIntNeedRounding/100;
    }

    public Sample(string theIntAsString)
    {
        _intField = preprocess(theIntAsString)
    }

    public Sample(int theIntNeedRounding)
    {
        _intField = preprocess(theIntNeedRounding)
    }

    public int IntProperty  => _intField;

    private readonly int _intField;
}

如果需要设置多个字段,ValueTuple会非常有用。

其他回答

是的,你可以在call base或this之前调用其他方法!

public class MyException : Exception
{
    public MyException(int number) : base(ConvertToString(number)) 
    {
    }

    private static string ConvertToString(int number) 
    { 
      return number.toString()
    }

}

在构造函数体之前,使用以下任意一个:

: base (parameters)

: this (parameters)

例子:

public class People: User
{
   public People (int EmpID) : base (EmpID)
   {
      // Add more statements here.
   }
}

我正在改进超级猫的答案。我想还可以做到以下几点:

class Sample
{
    private readonly int _intField;
    public int IntProperty
    {
        get { return _intField; }
    }

    void setupStuff(ref int intField, int newValue)
    {
        //Do some stuff here based upon the necessary initialized variables.
        intField = newValue;
    }

    public Sample(string theIntAsString, bool? doStuff = true)
    {
        //Initialization of some necessary variables.
        //==========================================
        int i = int.Parse(theIntAsString);
        // ................
        // .......................
        //==========================================

        if (!doStuff.HasValue || doStuff.Value == true)
           setupStuff(ref _intField,i);
    }

    public Sample(int theInt): this(theInt, false) //"false" param to avoid setupStuff() being called two times
    {
        setupStuff(ref _intField, theInt);
    }
}

是这样的:

public Sample(string str) : this(int.Parse(str)) { }

错误处理和使代码可重用是关键。我将字符串添加到int验证,如果需要,可以添加其他类型。用一个更可重用的解决方案来解决这个问题:

public class Sample
{
    public Sample(object inputToInt)
    {
        _intField = objectToInt(inputToInt);
    }

    public int IntProperty => _intField;

    private readonly int _intField;
}

public static int objectToInt(object inputToInt)
{
    switch (inputToInt)
        {
            case int inputInt:
                return inputInt;
            break;
            case string inputString:
            if (!int.TryParse(inputString, out int parsedInt))
            {
                throw new InvalidParameterException($"The input {inputString} could not be parsed to int");
            }
            return parsedInt;

            default:
                throw new InvalidParameterException($"Constructor do not support {inputToInt.GetType().Name}");
            break;
        }
}