2009-06-30 29 views
1

私はちょっとしたコーナーに自分を巻き込んだ。ここで私は(C#で)持っているものの簡易版である:C#でパラメータを使用せずにコンストラクタに情報を渡す

class OuterClass 
{ 
    private class BadClass 
    { 
     private int Data; 

     public BadClass() 
     { 
      Data = 0; 

      ... 
     } 
    } 

    T Build<T>(Object Input) 
    { 
     T x = new T(); 
     ... 
     return x; 
    } 

    void SomeMethod() 
    { 
     BadClass a = Build<BadClass>(anObject); 
     ... 
    } 
    ... 
} 

私が持っている問題は、私は今BadClassインスタンスを作成しているOuterClassのインスタンスに応じて、データの初期値を変更しなければならないということです。通常、私は単純にパラメータを取るBadClassコンストラクタ使用します。

public BadClass(int Data) 
{ 
    this.Data = Data; 
    ... 
} 

をしかし、私はパラメータなしBadClassのコンストラクタを持たなければならないので、私はいくつかの一般的なタイプでBadClassを使用しています。あまりにも悪い私はこのような何かすることはできません:私は、コンストラクタにパラメータを渡すことができないときに

Build<BadClass(5)>(anObject); 

を、どのように私は、コンストラクタ実行時の情報を提供していますか?
BadClass型の実行時インスタンスを作成し、必要な情報を与え、それをジェネリック型で使用することはできますか?私は私が働いている場合はinit関数を呼び出すためにビルドでテストを作成することができます私は例の一般的なタイプとしてリストを使用するが、それは完全に私のジレンマの深さを表現していなかった...

EDIT BadClassが、それは非常にハッキーです。私はそれについて少し醜い方法を見つけることを望んでいます。

+0

なぜコンストラクタをオーバーロードしませんか? – jle

+0

私はまだ何を達成しようとしているのか分かりません。 Buildメソッドにオブジェクトを渡しているという事実は、私には非常に怪しいものです。あなたが実装しようとしているパターンがありますか? –

+0

これは簡略化されたバージョンです。私は、私が働いている制約を説明しようとしています。 変更された工場パターンです。私は同じ基本クラスを持ついくつかのクラスを持っています。私は、クラスの適切なインスタンスを生成するために、上記のビルドを使用します。 明らかに私がここに示したものより複雑です。ファクトリに渡されるObjectはバイナリツリーのノードです。ファクトリは、BadClassをツリーに挿入する場所を決定し、その他いくつかの処理を行います。いくつかの異なるファクトリ関数があります。私は2段階のコンストラクタを使うことができますが、それは醜いでしょう。 – oillio

答えて

2

あなたはジェネリック医薬品のバリエーションである複数BadClassタイプを持っている必要がある場合は、あなたがあなたの継承ツリーを変更することで、そうすることができます。

class OuterClass { 
    private class BadClassBase { 
     // whatever BadClass does 
    } 
    private class BadClass : BadClassBase { 
     public BadClass(T item) { 
      ... 
     } 
    } 
} 

これがあなたの目的であるかどうかは不明ですが、リスト<BadClassBase>を作成することができます。

+0

これは私が必要としていたものに近いです。データの有効な値の数が限られている限り有効です。私はBadClassのためのパラメータのないコンストラクタを削除し、複数の継承クラスを作成しました。だから、私はBadClass1、BadClass2などがあり、その基底クラスはBadClassです。これらのクラスには、次のような単一のコンストラクタのみが含まれます。public BadClass1():base(1){} – oillio

6

List<BadClass>を作成すると、BadClassインスタンスは作成されません。先に行くとそのように作成していますが、それに追加するBadClassインスタンスを作成するとき、それはあなたがあなたのパラメータ化コンストラクタを呼び出すときです:

List<BadClass> a = new List<BadClass>(); 
a.Add(new BadClass(1)); 
a.Add(new BadClass(2)); 

ところで、BadClassインスタンスの構成を有するいるOuterClassに依存それはコードのにおいのビットです作成しています。あなたは何を達成しようとしていますか?

+0

なぜ、複数のコンストラクタを持つことができないでしょうか? ; D 'しかし、私はいくつかのジェネリック型でBadClassを使用していますので、私はパラメータのないBadClassコンストラクタを持っていなければなりません。 – wtaniguchi

+0

リストは悪い例でしたが、ジェネリック型は間違いなくそのコンストラクタにBadClassのインスタンスを作成できます。私はおそらくこの方法で回避することができますが、決して使用しないでくださいパラメータのないコンストラクタがあれば私のコードは悪化すると思います。 またBadClassを最初にコーディングしたとき、私はDataを調整する必要性を予期していませんでした。明らかに私はうんざりしました – oillio

+0

wtaniguchi - 複数のコンストラクタを持つことはできますが、ジェネリック型のクラスを使うということは、私はもはや有効なパラメータなしコンストラクタを構築することはできません。 – oillio

1

BadClassに初期化メソッドを与えることはできますか?あなたは1を作成するときに

private class BadClass 
{ 
    private int Data; 

    public BadClass() 
    { 
     Data = 0; 
     ... 
    } 

    public void Init(int dataValue) 
    { 
     Data = dataValue; 
    } 
} 

は、その後、それは次のようになります。

BadClass myInst = new BadClass(); // void constructor, as you require. 
myInst.Init(5); // Set the value to 5. 
+1

+1、私はこのパターンが好きです - それは文学の中のいくつかのもので "二相構造"と呼ばれています。 –

1

このようなことはどうですか。

using System.Collections.Generic; 

class OuterClass 
{ 
    private class BadClass 
    { 
     private int _data; 

     public BadClass() 
     { 
      _data = 0; 

     } 

     public int Data 
     { 
      get 
      { 
      return _data; 
      } 
      set 
      { 
      _data = value; 
      } 
     } 

    } 

    void SomeMethod() 
    { 
     List<BadClass> a = new List<BadClass>() 
     { 
      new BadClass() { Data = 7 }, 
      new BadClass() { Data = 9 } 
     }; 
    } 
} 
関連する問題