다른 생성자에서 하나의 생성자 호출
읽기 전용 필드에 값을 제공하는 두 개의 생성자가 있습니다.
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
You can also use this
keyword to invoke a constructor from another constructor
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);
}
}
The output of this sample program is
20
Constructor chaining i.e you can use "Base" for Is a relationship and "This" you can use for same class, when you want call multiple Constructor in single call.
class BaseClass
{
public BaseClass():this(10)
{
}
public BaseClass(int val)
{
}
}
class Program
{
static void Main(string[] args)
{
new BaseClass();
ReadLine();
}
}
Error handling and making your code reusable is key. I added string to int validation and it is possible to add other types if needed. Solving this problem with a more reusable solution could be this:
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;
}
}
참고URL : https://stackoverflow.com/questions/4009013/call-one-constructor-from-another
'code' 카테고리의 다른 글
NSString 값을 NSData로 어떻게 변환합니까? (0) | 2020.09.28 |
---|---|
파이썬에서 줄 수를 저렴하게 얻는 방법은 무엇입니까? (0) | 2020.09.28 |
Swift Beta 성능 : 배열 정렬 (0) | 2020.09.28 |
JSLint가 갑자기보고합니다. "use strict"의 함수 형식을 사용합니다. (0) | 2020.09.28 |
node.js에서 환경 변수를 어떻게 설정할 수 있습니까? (0) | 2020.09.25 |