1

If a class contains just string array variables, is there an easy way to initialize them all without having to type the same code over and over?

For example, if I have something like

[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 
}

and I want to assign values to to them, I want to avoid doing:

        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];
        ...

Sure, I could write those initialization in constructor but that still doesn't save me from having to manually initialize them all.

What's a good way to avoid this?

5
  • I’d suggest you rethink your design. In this case, it rather looks like you need only one array of structured data. Commented Sep 13, 2012 at 6:48
  • Why can't you use List<string> or List<CustomClass>, Where CustomClass has all your data Commented Sep 13, 2012 at 6:49
  • Agree with @Konrad; a YourTypeHere[] where YourTypeHere defines a PointIdentifier, PresentValue, AlarmState, etc would be far preferable. Also; I doubt they all need to be strings! Commented Sep 13, 2012 at 6:49
  • That is the interface I am given which follows a protocol known as SOAP. I can't deviate from it but if intermediate steps involve using list (or any other class) to meet what I need, then that is fine too. Commented Sep 13, 2012 at 6:50
  • that layout isn't mandated by SOAP; it is simply how you have chosen to lay out the data inside the SOAP envelope. Indeed, you can't change this arbitrarily (client(s) and server(s) must agree on the layout), but: on a green-field system, there is nothing in SOAP that makes you use that layout. Commented Sep 13, 2012 at 6:57

7 Answers 7

3

That is a pretty horrible way to manage your data, however, something like the following would work....

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

However! I strongly suggest you rethink this design. A better mechanism would be:

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;}
}

and have an array of that as a field:

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

then simply init the array:

points = new DiagnosticPoint[count];

and init each:

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

and access via:

var alarm = points[index].AlarmState;

(etc)

Sign up to request clarification or add additional context in comments.

Comments

1

You can use Reflection to do this:

public ReadDiagnosticEntirePointValuesResponse()
{
    GetType().GetFields(BindingFlags.Instance | BindingFlags.Public)
             .ToList()
             .ForEach(field => field.SetValue(this, new string[count]));
}

Comments

0

At least once you have to initialize them manually. if C'tor doesn't suit you, initialize in a new method.

Comments

0

You might want to look at reflection for that... Reading the class' proprties in a loop

Comments

0

This sounds like an awful class definition. Perhaps using an enum might be better.

If you could start with this:

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

You could then create a Dictionary<ReadDiagnostic, string[]> to hold your values that you were storing in your class.

You could even use LINQ to create your dictionary in one line of code:

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

This approach is still strongly-typed, but much easier to maintain than your current approach.

Comments

0

You could use the following:

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

However, using this will still have you initialize them manually. It's just a shortcut.

As others may already have suggested, using Collection Classes will make it a lot easier. I would recommend a Dictionary. Here is how you could implement it:

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) { ... }
}

Alternatively, you could also achieve the same by using a Multidimensional Array.

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

// access it like this
response[(int)Foo.Affect, 0] = "test";

Comments

0

You can use the array list to avoid of declaring the size.

1 Comment

But there might be a good reason for having fixed-length arrays. Possibly there needs to be exactly count elements, no more, no less.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.