Ответ 1
Как это:
public Sample(string str) : this(int.Parse(str)) { }
У меня есть два конструктора, которые передают значения только для чтения полей.
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;
}
Один конструктор получает значения напрямую, а другой выполняет некоторые вычисления и получает значения, затем устанавливает поля.
Теперь здесь подвох:
Есть идеи?
Как это:
public Sample(string str) : this(int.Parse(str)) { }
Если то, что вы хотите, не может быть достигнуто удовлетворительно без инициализации в своем собственном методе (например, потому что вы хотите сделать слишком много перед кодом инициализации, или обернуть его в try-finally, или как угодно), вы можете иметь любой или все конструкторы передают переменные только для чтения по ссылке на подпрограмму инициализации, которая затем сможет манипулировать ими по желанию.
public class Sample
{
private readonly int _intField;
public int IntProperty => _intField;
private void setupStuff(ref int intField, int newValue) => intField = newValue;
public Sample(string theIntAsString)
{
int i = int.Parse(theIntAsString);
setupStuff(ref _intField,i);
}
public Sample(int theInt) => setupStuff(ref _intField, theInt);
}
Перед телом конструктора используйте:
: base (parameters)
: this (parameters)
Пример:
public class People: User
{
public People (int EmpID) : base (EmpID)
{
// Add more statements here.
}
}
Я улучшаюсь после ответа supercat. Я думаю, что также можно сделать следующее:
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 SomeClass(int i)
{
I = i;
}
public SomeClass(SomeOtherClass soc)
: this(soc.J)
{
if (I==0)
{
I = DoSomethingHere();
}
}
Да, вы можете вызвать другой метод раньше, чем база вызовов или это!
public class MyException : Exception
{
public MyException(int number) : base(ConvertToString(number))
{
}
private static string ConvertToString(int number)
{
return number.toString()
}
}
Когда вы наследуете класс от базового класса, вы можете вызвать конструктор базового класса, создав экземпляр производного класса
class sample
{
public int x;
public sample(int value)
{
x = value;
}
}
class der : sample
{
public int a;
public int b;
public der(int value1,int value2) : base(50)
{
a = value1;
b = value2;
}
}
class run
{
public static void Main(string[] args)
{
der obj = new der(10,20);
System.Console.WriteLine(obj.x);
System.Console.WriteLine(obj.a);
System.Console.WriteLine(obj.b);
}
}
Выход примера программы равен
50 10 20
Вы также можете использовать ключевое слово this
для вызова конструктора из другого конструктора
class sample
{
public int x;
public sample(int value)
{
x = value;
}
public sample(sample obj) : this(obj.x)
{
}
}
class run
{
public static void Main(string[] args)
{
sample s = new sample(20);
sample ss = new sample(s);
System.Console.WriteLine(ss.x);
}
}
Результат этой примера программы -
20
Цепочка конструктора, т.е. вы можете использовать "Base" для отношения Is и "This" вы можете использовать для одного и того же класса, когда вы хотите вызвать несколько Constructor за один вызов.
class BaseClass
{
public BaseClass():this(10)
{
}
public BaseClass(int val)
{
}
}
class Program
{
static void Main(string[] args)
{
new BaseClass();
ReadLine();
}
}
Обработка ошибок и повторное использование вашего кода является ключевым. Я добавил строку к проверке 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 string");
}
return parsedInt;
default:
throw new InvalidParameterException($"Constructor do not support {inputToInt.GetType().Name}");
break;
}
}