1

現在、さまざまなクラスのさまざまなプロパティの値をシリアル/UDP ポートに出力できるようにする必要がある winforms アプリを設計しています。

実行時にこのプロジェクトのクラスのすべてのインスタンスを反復処理し、選択した束 (おそらく属性を使用して?) とそれに対応する文字列値をユーザーに表示する簡単な方法があるかどうか疑問に思っていました。これらの値の組み合わせ。

したがって、(単純化された)例として、2 つのクラスがあるとします。

public class ClassA
{
  public double Price{get;set;}
  public int Units{get;set}
  //other properties that I don't want visible to the user
}

public class ClassB
{
  public string Name{get;set;}
  public string Description{get;set;}
  //other properties not visible to the user
}

これらのクラスの多くのインスタンスを実行時にインスタンス化します (これらは必ずしも相互にリンク/参照/関連しているとは限りません)。

例えば

public ClassA Cars = new ClassA();
public ClassB Models = new ClassB();
public ClassA PCs = new ClassA();
//set properties of these instances
//etc.. more of these

これらのインスタンスをすべて収集し、対応するフィールドをユーザーに表示したいと思います。

Cars.Price = "1000";
Cars.Units = "3";
Models.Name = "BMW";
Models.Description = "Luxury Car";
PCs.Price = "3000";
PCs.Units = "20";

値は実行時に変更されることに注意してください。これは、データを送信するときに更新する必要があります。ここで誰かが私を正しい方向に向けてくれることを望んでいました。

編集

これは実行できない可能性があるようです。

オブジェクトのリストを保存する方法はありますか?これらのオブジェクトは私のプロパティ/フィールドを指し、その値を取得できますか? もちろん、これらのクラス インスタンスが 1 回だけ作成されると仮定すると、クラス プロパティ/フィールドを出力クラスに登録できます。次に、出力クラスはこのリストを反復処理し、それが指すオブジェクトの値を取得して、必要なデータを送信できますか?

例えば

class OutputData
{
  Dictionary<string,object> OutputDataList = new Dictionary<string,object>();

  public void RegisterData(string displayName, ref object dataField)
  {
    OutputDataList.Add(displayName,dataField);
  }

  //iterate over OutputDataList and get the value of the property/field it points to
}
4

2 に答える 2

2

これらのオブジェクトのすべてがアプリケーションの存続期間にわたって存在し、それらすべてを追跡する必要がある場合は、各クラスのコンストラクターで次のように実行できます。

public class Tracker
{
  public static List<object> AllObjects = new List<object>();
}

public class ClassA
{
   public ClassA()
   {
      Tracker.AllObjects.Add(this);
   }
   ...
}

そうすれば、追跡したいクラスを変更するだけで済み、インスタンスはリスト全体で追跡されます。どのフィールドを追跡するかという問題については、リフレクションを使用するか、より興味深いものをすべてのオブジェクトに格納することができます。おそらく、対象のFunc<List<string>>すべての値を返す a です。

add 行は次のようになります。

      Tracker.AllObjects.Add(() => 
          { 
            yield return "Name:" + this.Name; 
            yield return "Description:" + this.Description;
          });

その後、次のことができます。

var ouputLines = Tracker.AllObjects.SelectMany(o => o());
于 2012-05-25T05:02:51.883 に答える
1

これは何かのフィールドのように見えます:

public ClassA Cars = new ClassA();
public ClassB Models = new ClassB();
public ClassA PCs = new ClassA();

したがって、それについて明確にしましょう:

public class Something {
    public ClassA Cars = new ClassA();
    public ClassB Models = new ClassB();
    public ClassA PCs = new ClassA();
}

したがって、それらが何かのフィールドであると仮定すると、リフレクションを使用したクイックパスでそれらを見つけることができます。ここまでは順調ですね。

ただし、理解する必要があるのは、フィールドの名前 (「Cars」など) が変数のインスタンスに関連付けられていないことです。この場合は、そのフィールドを含むクラスのインスタンスに関連付けられていますSomething

理由を理解するには、次のコードを想像してください。

var a = new Something();
var b = new Something();
b.PCs = a.Cars;

これで、タイプ ClassA の変数が a.Carsb.PCs に格納されました。どのラベルを使用しますか?

これらのことの辞書を用意するか、そうでなければそれらが何と呼ばれるかを制限する必要があります。次のようなことができます:

public Dictionary<String, Object> myStuff = new Dictionary<String, Object> { { "Cars", new ClassA() }, { "Models", new ClassB() }, { "PCs", new ClassA() } };

// then, to get the field names and values

var someObject = myStuff["PCs"];
foreach (var fi in someObject.GetType().GetFields()) {
    var fieldName = fi.Name;
    var fieldValue = fi.GetValue(someObject);
    // Do something here
}
于 2012-05-25T04:55:34.400 に答える