0

I know this code doesn't work, because I tried it, but it gets the point across with what I want to accomplish. I'm using C# preview targeting Core 3.1

class MyClass
{
    public int size{ get; set; }
    private int[] myArray;

    public myClass()
    {
        myArray = new int[size];
    }

    public void SomeMethod()
    {
        var x = myArray[10]    <-- I want to be able to do this here
    }
}

public class MyOtherClass
{
    // I want this to still initialize myArray even though I didn't explicitly call a ctor
    var mc = new MyClass
    {
        size = 20;
    } 
}

When I run something like this, myArray get initialized to int[0]. I'm wondering if there is a syntax I'm unaware of that will make something like this work. The reason I'm asking is that I have like 10 variable that I need to use in a constructor call. That makes it a really long/ugly constructor signature and I don't like that. When I have more than 4 variables I like to use object initializers because it makes thinks less confusing for me.

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
master_ruko
  • 629
  • 1
  • 4
  • 22
  • 1
    `public int size { get => myArray?.Length ?? 0; } { set => myArray = new int[value]; } private int[] myArray;` then let setting `size` through object initialization instantiate your array. Your requirements have a certain code smell to me, but this would be a way to accomplish what you want. – itsme86 Sep 30 '20 at 21:39
  • Side note: If you follow .Net `List` class start with 4 items and grow as necessary... you probably also want to copy existing content on size changes... The growing arrays usually have size and count (total size and "actual" size). – Alexei Levenkov Sep 30 '20 at 21:49
  • @itsme86 thank you. I feel really stupid now, because I have actually done that in the past. This is the problem with writing code while sleep deprived. – master_ruko Sep 30 '20 at 22:07
  • @AlexeiLevenkov In most situations I would probably use ```List```, but I am intentionally using an array because I have to store a **** ton of data points and don't want the overhead that ```List``` will introduce. – master_ruko Sep 30 '20 at 22:12
  • 1
    @master_ruko I see... one extra int property (ignoring inlined indexer access)... Whatever floats your boat... but you may want to actually measure impact on retail build rather that claiming overhead... – Alexei Levenkov Sep 30 '20 at 22:30
  • 1
    as @itsme86 said, altering the objects API to avoid having a large constructor signature is probably a sign you need to refactor. If your object is doing one thing and needs the 10 args to do it then you're probably better off living with the ugly ctor, creating some POCO classes to group the args, using factory.. there's many options for refactoring ctor args that are better than exposing the internals of the object as setters. – MikeJ Oct 01 '20 at 02:07
  • @AlexeiLevenkov Everything I've read says arrays are better for storing huge amounts of values, especially if there's no need of the perks ```List``` provides. So your correct, I assumed the overhead. But, just to validate my assumption, I ran a test; it look ```List``` ~twice as long to store my data set and read each value once. Granted, ~1s vs ~500ms isn't that big of a deal. However, this was only one read; the data will be read many times in my real program. Also, the ```List``` ended up being 268.44MB, while the ```Short[]``` was only 150MB. So it isn't "one extra int property." – master_ruko Oct 01 '20 at 03:23
  • The memory usage difference seem to be very strange - I don't believe pre-allocated list wastes so much space (according to https://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs,cf7f4095e4de7646 there is no extra space allocated), otherwise numbers look plausible as you measured both setting and getting data (I get 20-70% difference depending on element size which is close enough to your 100%). Note that just reading difference should be in single percent difference - https://stackoverflow.com/questions/454916/performance-of-arrays-vs-lists. – Alexei Levenkov Oct 01 '20 at 04:03
  • @AlexeiLevenkov The test shown in the accepted answer of the SO link you provided is almost verbatim what I did. The only difference is that I used shorts and stored 50M entries. I suspect the time difference diverges as the number of values goes up. – master_ruko Oct 01 '20 at 04:57

1 Answers1

3

You can execute arbitrary code in a setter, so you could initialize myArray, whenever size is changed:

public int size { 
     get {return myArray.Length;} 
     set {myArray = new int[value];}
}
private int[] myArray = new int[0];

I am somewhat doubtful whether that makes the code more readable, but it should work

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
HugoRune
  • 13,157
  • 7
  • 69
  • 144