8

非常に一般的なシナリオ:複数のインスタンス変数を持つクラスと、複数のパラメーターを受け入れるコンストラクターがあります。どういうわけか一方を他方にバインドできますか?すべてのパラメーターをインスタンス変数に割り当てることは非常に冗長であり、設定より規約の原則でカバーできる(そしてカバーする必要がある)状況の1つです。私のサンプルコードは次のようになります。

public class myClass
{    
    private object param1;
    private object param2;
    private object param3;
    private object param4;

    public myClass(object param1, object param2, object param3, object param4)
    {
        this.param1 = param1;
        this.param2 = param2;
        this.param3 = param3;
        this.param4 = param4;
    }
}

これを取り除き、C#に魔法を自動的に実行させる簡単な方法はありますか?

4

3 に答える 3

5

これをカバーするC#言語には何もありません。ツールはコードを生成できますが、必ずしも最新の状態に保たれているとは限らず、コードが存在して表示されたままになります。リフレクションを使用する一部のシナリオでは、これを実行できる可能性があります。例

public MyClass(object param1, object param2, object param3, object param4)
{
    Helpers.PopulateFromConstructor(this, param1, param2, param3, param4);
}

...値をパラメータと同じ順序で指定し、名前をフィールドなどと同じに保つ必要がある場合。フィールドが。の場合にも問題が発生する可能性がありますreadonly

個人的には、私はそれを吸います-必要に応じてツールを使用してコードを生成しますが、それ以外の場合はそれを使用します。

特にnullityの周りで、フィールドを設定するときに検証を行うことができることに注意してください。したがって、コンストラクター本体は実際には次のようになります。

public myClass(object param1, object param2, object param3, object param4)
{
    this.param1 = Preconditions.CheckNotNull(param1);
    this.param2 = param2;
    this.param3 = Preconditions.CheckNotNull(param3);
    this.param4 = param4;
}

(もちろん、適切なPreconditionsクラスの場合。私は日常のコーディングで使用しているので、JavaコードでGuavaからのアイデアに無償でニックネームを付けました。これはNoda Timeでも使用しているアプローチです。)

于 2012-08-28T12:35:39.920 に答える
4

「...設定より規約の原則でカバーされる可能性があります(そしてカバーされるべきです...」

「設定より規約」は通常、言語自体ではなく、APIまたはMVCやEntityFrameworkなどのフレームワークに適用されます。APIは通常、焦点を絞った、再利用可能な、そして何よりも機能の抽象化を簡素化するものです。この状況では、口述の慣習は、機能を損なうことなく構造を推進するのに役立ちます。

ただし、これはプログラミング言語には当てはまりません。言語は広範で低レベルであり、比較すると複雑です。言語の価値を薄めることなく、ユーザーをできるだけ制限しないようにする必要があります。そのような広い「慣習」が非常に規範的であると仮定します。これを超えると、指定された名前のパラメーターを常に同じ名前のプライベートフィールドに割り当てる必要があるとコンパイラーが想定するのは危険です。

一つには、あなたの慣習だけが一般的に使われるものではありません。たとえば、一般的なコーディングスタイルの1つは、アンダースコア主導のプライベートフィールド(_param1)を提案しますが、これは慣例では見逃されます。コンストラクターには、これらの割り当て以外のロジックが含まれている可能性があります。その場合、規則は単純すぎます。「規則駆動型」コードは、他のコンストラクターロジックの前または後に実行する必要がありますか。

最も重要なことは、そのような規則をどのように無効にするのでしょうか。コンストラクターで他の方法で消費するparam1場合でも、規則を実行しますか?コンストラクターで、別の値をに割り当てた場合はどうなりthis.param1ますか?あなたの慣習は、ユーザーが追加したコードの前または後に発生する必要がありますか?

これらの簡単な質問(多くの人が非常に異なって等しく有効な答えを持っているでしょう)でさえ、そのような慣習が見た目ほど明白ではなく、簡単に定義されていないことを示唆するのに十分です。

于 2012-08-28T12:39:30.157 に答える
2

この種のことを実行できるプラグインはたくさんありますが、一致するコンストラクターが存在しないときにモデル呼び出しからコンストラクターを生成するVS2010 +のネイティブ機能を使用している場合は、単純なキーボードショートカットを使用して作業を行うことができます。 。

つまり、私がスタブクラスの場合:

class MyClass{

}

そして、どこかのメソッドで次のように記述します。

object p1, p2, p3;
//...  (get values for p1-3)
var a = new MyClass(p1, p2, p3);

そのようなコンストラクターが存在しない場合、小さなヘルパーボタンが表示されます。ALT+SHIFT+F10それをクリックするか、 (デフォルトで)を押すと、スタブコンストラクターを生成するオプションの1つであるメニューが表示されます。これにより、MyClassコードが次のように変更されます。

class MyClass
{
    private object p1;
    private object p2;
    private object p3;

    public MyClass(object p1, object p2, object p3)
    {
        // TODO: Complete member initialization
        this.p1 = p1;
        this.p2 = p2;
        this.p3 = p3;
    }

}
于 2012-08-28T12:45:50.653 に答える