何らかの方法でカプセル化されるべきいくつかの機能を必要とするクラスがあります。ネストされた型または1対1のマップされたクラスのための他のソリューション
私はネストされたクラスを考えていて、その機能に加えていくつかの状態を入れました。 これら2つのクラスの関係は1対1です。
外部クラスメンバの変数やメソッドにアクセスする際の問題は、static
と宣言する必要があります。別の解決策は、外部クラスの参照を内部クラスに渡すことです。
問題のベストプラクティスは何ですか?
何らかの方法でカプセル化されるべきいくつかの機能を必要とするクラスがあります。ネストされた型または1対1のマップされたクラスのための他のソリューション
私はネストされたクラスを考えていて、その機能に加えていくつかの状態を入れました。 これら2つのクラスの関係は1対1です。
外部クラスメンバの変数やメソッドにアクセスする際の問題は、static
と宣言する必要があります。別の解決策は、外部クラスの参照を内部クラスに渡すことです。
問題のベストプラクティスは何ですか?
using System;
class OuterType
{
private static OuterType _instance;
public OuterType()
{
_instance = this;
}
private String Message
{
get { return "Hello from OuterType"; }
}
public void testInnerType()
{
InnerType innerType = new InnerType();
Console.WriteLine(innerType.FormattedOutertMessage);
}
private class InnerType
{
private readonly OuterType _outerType = _instance;
public String FormattedOutertMessage
{
get { return _outerType.Message.ToUpper(); }
}
// InnerType doesn't need to dispose any object of OuterType.
}
}
そして、それは次のように動作します。
class Program
{
static void Main(string[] args)
{
OuterType outerType = new OuterType();
outerType.testInnerType();
Console.ReadKey();
}
}
しかし、これは良いアイデアであるかない場合、私はわかりません?!
ネストされたクラスが悪いと言うほどには行きませんが、確かに「いたずら」になる可能性があります。ネストされたクラスが解決する問題はほとんどなく、エレガントに。
だから、本当にあなたの特定の状況によって異なりますが、考慮すべきいくつかのものがあります:
入れ子になったクラスが公開されようとしていますか? OuterType + InnerType
ソースファイルは平均的に大きく、読みやすく、理由が分かりにくいです(ただし、これは戦略的な使用によって軽減される可能性があります)。部分クラスの)。
Visual Studioのコード解析では、ネストされた公開クラスについて大声で苦情を言います(フレームワークデザインガイドラインでは適切なフォームではありません).FxCopを使用している場合は、例外を設定する必要があります。
詳細を掲載すると、より詳細なガイダンスを提供できる場合があります。
もし私がここに持ってくると私のシナリオは非常に複雑で、おそらく誰もそのような質問を読むことはありません。私はできるだけコンセプトを単純化しました。どのように元のクラスのすべてにアクセスすることができます機能のセットをカプセル化するには? – Xaqron
しかし、「機能セットをカプセル化する」ことは、オブジェクト指向設計の本質であり、確かにネストされたクラスの使用を必要としません。一般的に、Single Responsibility Principleは、そのような機能が将来の変更のために他の理由から「カプセル化」され、「分離」されることを示唆します。私は、あなたがここで直面していることについていくつかの細部が本当に光を当てると思う。 – lesscode
約6ヶ月前とまったく同じ問題が発生しましたが、別の理由があります。私たちは約20の「普通の」クラスと1つの巨大な木星サイズのクラスを持っていました。
実際には、親に加えて、2つの子が両方とも親に対して1対1の関係で2人必要です。
最初の試行では、各子のコンストラクタで 'this'の参照を渡し、次に.Parentメソッドを使用してバックアップを移動する旧式のパターンを使用しました。それはGCの問題による悪夢であり、短時間でより良い解決策を模索しました。
ベストソリューション(今日でも使用されています)は、親に照会する必要がある子のメソッドで親クラスの型の参照を受け入れるだけでした。これは非常にうまくいって、GCはそれを気に入って、すべてがインスタンス化され、期待どおりに解放されました。コードはより管理しやすく、より整理されており、今すぐに時間をかけて投資を行ってうれしいです。唯一それを必要とする方法で親クラスへの参照を受け入れる子オブジェクトのメソッドで
Parent
|
+-Child1
|
+-Child2
:
だから、それは私の推薦だろう。
これは実際にはADOのようなものです。ネットが開発され、必要な方法で互いに参照を受け入れる独立したオブジェクトがあります。
ありがとうございました。私はコンストラクタで親の参照を渡すことを考えていた。私は両方の子供がファイナライズされたら、あなたは親も処分することができますが、 'GC'問題は起こらないと思います。 'GC'は彼が望むときにそれを(処分する)し、特別な場合を除いてこれは良いです。その場合、 'GC'は強制的に(' GC.Collect() 'を実行することができますが、これはパフォーマンス・キラーです)。答えとして別の解決策を追加しますが、それが既知のパターン、ベストプラクティスかどうかはわかりません。 – Xaqron
実際には、コンストラクタで親の参照を渡すことは問題ではありません。問題は、子が参照を.Parentプロパティの親に戻したときの循環参照でした。 GCは2つのオブジェクトへの唯一の参照がお互いにあることを確認することを望んでいましたが、そうではありませんでした。とにかく、.Parentプロパティを実行しない場合、コンストラクタで親を渡すと問題はありません。 – Flipster
あなたはこれまでのものを私たちに見せてもらえますか? –
内部クラスは、外部クラスのデータで動作するデータ処理クラスの一種です。私は外部クラスのすべてにアクセスする必要がありますが、何らかの方法でカプセル化されています。この機能を新しいクラスとして定義することは良い考えではありません。 – Xaqron