How to create an automatically created element array, such as int arrays of user-defined type?

After declaring an int array, for example:

int[] test = new int[5]; 

All elements of the array are automatically initialized to 0 . In any case, can I create a class that will be automatically initialized when creating an array, such as int arrays?

For instance:

 MyClass[] test2 = new MyClass[5]; 

Still require me to call the constructor; but with int constructor is magically called.

What code / operators of int class allow this behavior?

+4
source share
5 answers

Update:

I removed the new() constraint to accept the class without a parameterless constructor . However, this will also agree with an abstract class or interface that will be used as the type parameter, and it will throw an exception at runtime if the type cannot be created.

One more note: the CreateArray<T> method also applies to value types ; that is, in addition to pointer types and types that have the TypeAttributes.Abstract 1 attribute, you can create any type of array with it.

1 : Interfaces are also abstract. Static classes are abstract and sealed.


The difference is that int is a value type, but your class may not be.

Declare MyClass as struct MyClass{ } , then it will behave just like you create an int array.

If you want to create an array of reference types, the following code will simply do this:

 public static class TestClass { public static T[] CreateArray<T>(int length, params object[] args) { var elementType=typeof(T); var array=(T[])Array.CreateInstance(elementType, length); for(; length-->0; array[length]=(T)Activator.CreateInstance(elementType, args)) ; return array; } public static void TestMethod() { var array=CreateArray<MyClass>(5, /* default arguments */ ); } } 

The default argument is the arguments you pass to the constructor. The code creates an array, then creates instances of the type with the given arguments and initializes the array with instances.

Note that length passed as the size of the array, and then used as an index in the for-loop.

Documentation:

+3
source

The problem is that MyClass is a reference type, so the default value is null. Since you are not initializing the objects in the array, they are zero. You could write an assistant, for example:

 T[] InitializeArray<T>(int length) where T : new() { T[] array = new T[length]; for (int i = 0; i < length; ++i) { array[i] = new T(); } return array; } 

and then initialize the array:

 MyClass[] something = InitializeArray<MyClass>(5); 
+4
source

The int array is not magically set to 0. int is a value type with a default value of 0, where as MyClass is a reference type with a default value of null .

If you want to create an array with all initialization, you can use the free extension method:

 public static T[] InitializeAll<T>(this T[] source) where T : new() { if(source != null) { for(var i = 0; i < source.Length; ++i) { source[i] = new T(); } } return source; } var test2 = new MyClass[5].InitializeAll(); 

Or a mandaleeka solution using a loop.

Edit: I am restoring my original solution since Guffa comment is needed for context

 public static T[] CreateArray<T>(int size) where T : new() { return Enumerable.Repeat(new T(), size).ToArray(); } 
+4
source

Change MyClass as a structural data type, i.e.: public struct MyClass .

+2
source

This is due to the difference between Value Types and Reference Types .

"A data type is a value type if it contains data within its own memory allocation." whereas "Link type contains a pointer to another memory cell in which data is stored."

Common examples of value types:

  • All numeric data types
  • Boolean, Char and Date
  • All structures, even if their elements are reference types
  • Enumerations, since their base type is always SByte, Short, Integer, Long, Byte, Short, UInteger, or ULong

Common examples of reference types:

  • Line
  • All arrays, even if their elements are value types
  • Class types such as Form
  • Delegates

All value types are initialized to the default value (zero for numeric types), and reference types indicate null .

Ad:

 int num; 

Does not initialize the num variable. Therefore, num cannot be used. C # requires that each variable be set to some value (be it null or a number) before using it.

The same applies to reference types:

 //un-initialized, therefore cannot be used until a value is given(A compiler error will occur) string str; 

However, the announcement:

 int[] numbers = new int[5]; 

It calls the initialization of the array (therefore, calls the constructor of the array), which then calls the initialization of each of the default elements for the int value (i.e., zero).

Using the same method in a reference type gives the same result:

 string[] strings = new string[5]; 

Invokes array initialization and, therefore, creates a null string array (which is the default value for all types of links).

Structures are the data type you are looking for. Structures are value types and therefore cannot be set to null . Since they cannot be set to null , they must have a specific default value. The default value is determined by the default constructor .

The structure can be defined as follows:

 struct MyStructName { //Members of the struct, like a class, default value is 0. int myNumber; //Structs can have members whose data type is a reference type //Default value is null. string myString; //Every struct has a default constructor, though you cannot define one. //The compiler generates one for you that initializes every member to it's //default value. } 

This will determine the data type that contains the members, myNumber and myString, which cannot be set to null .

 //Array of MyStructName, the default constructor is called and each value is initialized MyStructName[] data = new MyStructName[5]; //Loop and print results for(int i = 0; i < data.Length; i++) { //Prints the index, number and the string or "null" Console.WriteLine("{0}: myNumber: {1}, myString: \"{2}\"", i, data[i].myNumber, data[i].myString != null ? data[i].myString : "null"); } 
0
source

Source: https://habr.com/ru/post/1488190/


All Articles