Best way to “push” into C# array

后端 未结 12 2661
没有蜡笔的小新
没有蜡笔的小新 2021-02-13 14:25

Good day all

So I know that this is a fairly widely discussed issue, but I can\'t seem to find a definitive answer. I know that you can do what I am asking for using a L

12条回答
  •  故里飘歌
    2021-02-13 14:52

    C# is a little different in this respect with JavaScript. Because of the strict checks, you define the size of the array and you are supposed to know everything about the array such as its bounds, where the last item was put and what items are unused. You are supposed to copy all the elements of the array into a new, bigger one, if you want to resize it.

    So, if you use a raw array, there's no other way other than to maintain the last empty, available index assign items to the array at this index, like you're already doing.

    However, if you'd like to have the runtime maintain this information and completely abstract away the array, but still use an array underneath, then C# provides a class named ArrayList that provides this abstraction.

    The ArrayList abstracts a loosely typed array of Objects. See the source here.

    It takes care of all the issues like resizing the array, maintaining the last index that is available, etc. However, it abstracts / encapsulates this information from you. All you use is the ArrayList.

    To push an item of any type into the underlying array at the end of the underlying array, call the Add method on the ArrayList like so:

    /* you may or may not define a size using a constructor overload */
    var arrayList = new ArrayList(); 
    
    arrayList.Add("Foo");
    

    EDIT: A note about type restriction

    Like every programming language and runtime does, C# categorizes heap objects from those that will not go on the heap and will only stay on the function's argument stack. C# notes this distinction by the name Value types vs. Reference types. All things whose value goes on the stack are called Value types, and those that will go on the heap are called Reference types. This is loosely similar to JavaScript's distinction between objects and literals.

    You can put anything into an ArrayList in C#, whether the thing is a value type or a reference type. This makes it closest to the JavaScript array in terms of typelessness, although neither of the three -- the JavaScript array, the JavaScript language and the C# ArrayList -- are actually type-less.

    So, you could put a number literal, a string literal, an object of a class you made up, a boolean, a float, a double, a struct, just about anything you wanted into an ArrayList.

    That is because the ArrayList internally maintains and stores all that you put into it, into an array of Objects, as you will have noted in my original answer and the linked source code.

    And when you put something that isn't an object, C# creates a new object of type Object, stores the value of the thing you put into the ArrayList into this new Object type object. This process is called boxing and isn't very much unlike the JavaScript boxing mechanism.

    For e.g. in JavaScript, while you could use a numeric literal to invoke a function on the Number object, you couldn't add something to the number literal's prototype.

    // Valid javascript
    var s = 4.toString();
    
    // Invalid JavaScript code
    4.prototype.square = () => 4 * 4;
    var square = 4.square();
    

    Just like JavaScript boxes the numeric literal 4 in the call to the toString method, C# boxes all things that are not objects into an Object type when putting them into an ArrayList.

    var arrayList = new ArrayList();
    
    arrayList.Add(4); // The value 4 is boxed into a `new Object()` first and then that new object is inserted as the last element in the `ArrayList`.
    

    This involves a certain penalty, as it does in the case of JavaScript as well.

    In C#, you can avoid this penalty as C# provides a strongly typed version of the ArrayList, known as the List. So it follows that you cannot put anything into a List; just T types.

    However, I assume from your question's text that you already knew that C# had generic structures for strongly typed items. And your question was to have a JavaScript like data structure exhibiting the semantics of typelessness and elasticity, like the JavaScript Array object. In this case, the ArrayList comes closest.

    It is also clear from your question that your interest was academic and not to use the structure in a production application.

    So, I assume that for a production application, you would already know that a generic / strongly typed data structure (List for example) is better performing than its non-typed one (ArrayList for example).

提交回复
热议问题