SO (および他の場所) でこのトピックに関する多くの議論を読みましたが、明確な答えを得ることができませんでした。
特定のクラス A が特定のクラス B によってのみ作成されるようにしたいと考えています。C++ では、A のコンストラクターをプライベートにし、B をフレンドとして指定します。B だけが A を作成できるようになりました。
実際にC#でこれを行う慣用的な方法は何ですか?
SO (および他の場所) でこのトピックに関する多くの議論を読みましたが、明確な答えを得ることができませんでした。
特定のクラス A が特定のクラス B によってのみ作成されるようにしたいと考えています。C++ では、A のコンストラクターをプライベートにし、B をフレンドとして指定します。B だけが A を作成できるようになりました。
実際にC#でこれを行う慣用的な方法は何ですか?
これにはプライベート内部クラスを使用できます。
ただし、これは用途が限られています。
class B
{
private class A
{
}
}
C# で C++ スタイルのアプローチを使用することはできません。
以前にこれに遭遇したことがありますが、通常はクラス A abstract
(継承が必要) とコンストラクターprotected
(クラスから継承するクラスのみがコンストラクターを呼び出すことができます) を作成することで解決します。
次に、クラス B 内にクラスを作成しprivate
('_A' のように呼ばれます)、A から継承します (_A 内に追加のコードはありません)。_A は public であるコンストラクターを定義します。したがって、B に可視です (_A はプライベート)。
B 内で _A のインスタンスを作成し、それらを A として返すことができます ( polymorphismを介して)。
クラス A がその中に実装されている場合、クラス B のコード ファイルが巨大になるため、私はパブリック インターフェイスよりもこのアプローチを好みます。ただし、これは私の好みにすぎません。他の人は異なる意見を持っている可能性があります。
abstract class A
{
protected A()
{
}
/* implementation details... */
}
public class B
{
public A GetInstance()
{
return new _A();
}
private class _A : A
{
public _A()
{
}
}
}
それは実行可能ですが、厄介な方法です。おそらく、C++ の「友達」の概念よりも厄介です。
特定のタイプのみがこのメソッドを呼び出すことを許可するプライベート コンストラクターと静的ファクトリ メソッドを宣言できます (StackFrame をチェックすることにより)。
public class Foo
{
private Foo() { }
public static Foo Create()
{
if(GetCallingType() != typeof(Bar))
{
throw new Exception("Only Bar can create Foo");
}
return new Foo();
}
private static Type GetCallingType()
{
return new StackFrame(2, false).GetMethod().DeclaringType;
}
}
外部コードは を参照する必要があると想定していますがA
、インスタンスを作成することはできません。
これを実現する簡単な方法はありません。A
のコンストラクターを作成するinternal
と、同じアセンブリ内のコードのみA
がそれを構築できます (リフレクションを使用せずに)。
のインスタンスを作成し、インデックス1 のフレームをチェックして、それが のメソッドからのものかどうかを確認できますが、これはパフォーマンスの問題につながる可能性があり、一種のハックです。StackTrace
B