1

クラスに文字列配列変数だけが含まれている場合、同じコードを何度も入力せずにすべてを初期化する簡単な方法はありますか?

たとえば、次のようなものがある場合

[Serializable]
public class ReadDiagnosticEntirePointValuesResponse
{
    public string[] pointidentifier;
    public string[] presentvalue;
    public string[] priorityarray;
    public string[] alarmstate;
    public string[] outofservice;
    public string[] correctvalue;
    public string[] affect;
    public string[] covenable;
    public string[] covincrement;
    public string[] covtarget;
    public string[] covlifetime;
    public string[] historyenable;
    public string[] historyincrement;
    public string[] elapsedactivetime;
    public string[] feedbackvalue;
    public string[] rawvalue;
    ...//A lot more 
}

そして、それらに値を割り当てたいのですが、次のことは避けたいです:

        ReadDiagnosticEntirePointValuesResponse response = new ReadDiagnosticEntirePointValuesResponse();


        response.affect = new string[count];
        response.alarmstate = new string[count];
        response.correctvalue = new string[count];
        response.covenable = new string[count];
        response.covincrement = new string[count];
        response.covlifetime = new string[count];
        response.covtarget = new string[count];
        response.elapsedactivetime = new string[count];
        response.feedbackvalue = new string[count];
        response.historyenable = new string[count];
        response.historyincrement = new string[count];
        response.outofservice = new string[count];
        response.pointidentifier = new string[count];
        response.presentvalue = new string[count];
        response.priorityarray = new string[count];
        response.rawvalue = new string[count];
        ...

確かに、これらの初期化をコンストラクターで記述できますが、それでもすべてを手動で初期化する必要がなくなります。

これを回避する良い方法は何ですか?

4

7 に答える 7

3

これはデータを管理するための非常に恐ろしい方法ですが、次のような方法でうまくいきます....

foreach(var field in GetType().GetFields()) {
    if(!field.IsStatic) field.SetValue(this, new string[count]);
}

でも!このデザインを再考することを強くお勧めします。より良いメカニズムは次のとおりです。

class DiagnosticPoint // TODO: rename as appropriate
{  // TODO: check these all need to be strings
    public string Affect {get;set;}
    public string AlarmState {get;set;}
    ...
    public string RawValue {get;set;}
}

その配列をフィールドとして持っています:

public class ReadDiagnosticEntirePointValuesResponse
{
    DiagnosticPoint[] points;
    ...

次に、配列を初期化します。

points = new DiagnosticPoint[count];

そしてそれぞれを初期化します:

for(int i = 0 ; i < count ; i++) points[i] = new DiagnosticPoint();

次の方法でアクセスします。

var alarm = points[index].AlarmState;

(等)

于 2012-09-13T06:50:34.100 に答える
1

これを行うために使用できますReflection

public ReadDiagnosticEntirePointValuesResponse()
{
    GetType().GetFields(BindingFlags.Instance | BindingFlags.Public)
             .ToList()
             .ForEach(field => field.SetValue(this, new string[count]));
}
于 2012-09-13T06:50:05.490 に答える
0

これはひどいクラス定義のように思えます。おそらく、を使用するenum方が良いかもしれません。

これで始めることができれば:

public enum ReadDiagnostic
{
    pointidentifier,
    presentvalue,
    priorityarray,
    alarmstate,
    outofservice,
    correctvalue,
    affect,
    covenable,
    covincrement,
    covtarget,
    covlifetime,
    historyenable,
    historyincrement,
    elapsedactivetime,
    feedbackvalue,
    rawvalue,
}

Dictionary<ReadDiagnostic, string[]>次に、クラスに格納していた値を保持する を作成できます。

LINQ を使用して、1 行のコードで辞書を作成することもできます。

var readDiagnosticEntirePointValues =
    typeof(ReadDiagnostic)
    .GetEnumValues()
    .Cast<ReadDiagnostic>()
    .ToDictionary(x => x, x => new string[count]);

このアプローチは依然として厳密に型指定されていますが、現在のアプローチよりも保守がはるかに簡単です。

于 2012-09-13T07:09:40.283 に答える
0

以下を使用できます。

response.affect = response.alarmstate = response... = new string[count];

ただし、これを使用すると、手動で初期化する必要があります。それはただのショートカットです。

他の人がすでに示唆しているように、コレクション クラスを使用すると、はるかに簡単になります。Dictionaryをお勧めします。これを実装する方法は次のとおりです。

enum Foo { Affect, AlarmState, CorrectValue, ... }

public void InitializeArrays(int count)
{
    Dictionary<Foo, string[]> response = new Dictionary<Foo, string[]>();

    // easy initialization of string arrays
    foreach (Foo foo in Enum.GetValues(typeof(Foo)))
    {
        response.Add(foo, new string[count]);
    }

    // use this to access the string arrays
    response[Foo.Affect][0] = "test";

    if (response[Foo.CorrectValue].Length > 0) { ... }
}

または、多次元配列を使用して同じことを達成することもできます。

// initialize it like this
string[,] response = new string[Enum.GetValues(typeof(Foo)).Length, count];

// access it like this
response[(int)Foo.Affect, 0] = "test";
于 2012-09-13T07:14:05.073 に答える
0

配列リストを使用して、サイズの宣言を回避できます。

于 2012-09-13T06:48:54.350 に答える
0

少なくとも一度は手動で初期化する必要があります。C'tor があなたに合わない場合は、新しいメソッドで初期化してください。

于 2012-09-13T06:49:34.123 に答える
0

そのためにリフレクションを見たいと思うかもしれません...クラスのプロパティをループで読む

于 2012-09-13T06:49:34.757 に答える