読み取り専用フィールドに値を供給する2つのコンストラクタがあります。
class Sample
{
public Sample(string theIntAsString)
{
int i = int.Parse(theIntAsString);
_intField = i;
}
public Sample(int theInt)
{
_intField = theInt;
}
public int IntProperty
{
get { return _intField; }
}
private readonly int _intField;
}
一方のコンストラクタは直接値を受け取り、もう一方のコンストラクタは何らかの計算を行って値を取得してからフィールドを設定します。
今ここにキャッチがあります:
何か案は?
このような:
public Sample(string str) : this(int.Parse(str)) {
}
初期化を独自の方法で行わないと満足のいく結果が得られない場合(例えば、初期化コードの前でやり過ぎたり、try-finallyでラップしたりするなどの目的で)コンストラクタは初期化ルーチンを参照することによって読み取り専用変数を渡します。これにより、初期化ルーチンは自由に操作できるようになります。
class Sample
{
private readonly int _intField;
public int IntProperty
{
get { return _intField; }
}
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.
}
}
私はスーパーキャットの答えを改善しています。次のようなこともできると思います。
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);
}
}
サンプルプログラムの出力 is
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
コンストラクタチェーン つまり、Is a relationに "Base"を、同じクラスに "This"を使用できます。単一の呼び出しで複数のConstructorを呼び出したい場合。
class BaseClass
{
public BaseClass():this(10)
{
}
public BaseClass(int val)
{
}
}
class Program
{
static void Main(string[] args)
{
new BaseClass();
ReadLine();
}
}