What do square brackets mean in this context in C#? - c#

What do the square brackets mean in a new expression in C# as follows:
public class MyClass
{
public string Name { get; set; }
}
// ...
var x = new MyClass[0]; // <-- what is this?

This is an array declaration
The use of var just allows the compiler to decide on the type
MyClass[] classArray = new MyClass[0];
The 0 inside the [] indicates that the number of array 'spaces' is 0
var classArray = new MyClass[5];
This will create an array of length 5, and the use of var will allow the compiler to decide on the type, which will be MyClass[]
You can access each place in the array I created above by using indexers, mentioned in another answer, similar to this, let's say MyClass has a property called name with public get and set accessors(stupid example I know)
classArray[1] = new MyClass();
classArray[1].Name = "Daniel's class";
This allows us to access the MyClass object held in the second array placement, this is indexing
We can also create an array like this, let's say that the MyClass has a constructor that takes a string for the Name property
var x = new [] {
new MyClass("Daniels"),
new MyClass("Yours"),
new MyClass("Ours")
};
Forgive me for my bad examples

Related

Get reference to variable and avoid copying it unnecessarily

Suppose I have a class like this:
class Array{
int[] values;
}
Now suppose I have a class that stores a lot of Arrays:
class ArrayOfArrays{
Array[] arrays;
}
Suppose, for some reason, I want to get the last Array of arrays and put in a variable (for better readability). In C, I would do like Array last = &ArrayOfArraysObject.arrays[lastIndex]. As I won't modify it, for better performance, I don't need to copy the whole array, just a reference do the job.
Can I have this kind of behaviour in C# ? (without using function calls, I don't want to create a function just to use the keyword ref, it looks like overkill)
You could create a public property that returns the last element of arrays.
class ArrayOfArrays
{
Array[] arrays;
public Array LastOfArrays { get { return arrays.Last(); } }
}
Test it:
var aoa = new ArrayOfArrays();
// Initialize and enter data here
//When you want to use the last item:
var last = aoa.LastOfArrays;
last.values[0] = 333;
Now, aoa.arrays[LastElement].values[0] would also be 333. So you essentially do keep the reference here, and does not copy the entire array.
Confirmation:
Arrays already use references in C#. You don't have to do anything special, and you get the behavior you want:
int[][] foo = new int[][] { new int[] {1,2,3}, new int[]{4,5,6}, new int[]{7,8,9} };
var bar = foo[2];
foo[2][2] = 0; // make a change **after** assigning to bar
Console.WriteLine(bar[2]); // outputs "0" -- bar knows about the change
bar[1] = 6; // same thing, but in reverse
Console.WriteLine(foo[2][1]); // outputs "6" -- foo knows about the change
In the example above, foo[2] and bar are references to the same array in memory. bar was not just a copy.

Array instantiation of an object

public class Teacher{
public string imageUrl;
public TeacherEducationalQualification[] teacherEducationalQualification;
}
public class TeacherEducationalQualification{
public string NameOfDegree;
public string NameOfUniversity;
public int YearOfGraduation;
}
In the above codes when I instantiate Teacher class like
Teacher teacher= new Teacher();
This works fine but when I instantiate array in Teacher class for object 'teacher'
teacher.teacherEducationalQualification = new TeacherEducationalQualification[5];
It gives me an error 'Object reference not set to an instance of an object' whenever i try to access any variable to set values in it.
teacher.teacherEducationalQualification[1].NameOfDegree= "abc";
Please Help.
After you initialize an array of objects (reference type) its items will be null. You have to iterate (loop) through the array and initialize each item.
If you want to set each item individually however, you can do something like this
Teacher teacher = new Teacher();
teacher.teacherEducationalQualification = new TeacherEducationalQualification[5];
// Initialize item at index 0; indices start with 0 so the 1st item has index 0
teacher.teacherEducationalQualification[0] = new TeacherEducationalQualification();
teacher.teacherEducationalQualification[0].NameOfDegree= "abc";
// Initialize item at index 1
// Initialize item at index 2
// Initialize item at index 3
// Initialize item at index 4; this is the last index, your 5th item
teacher.teacherEducationalQualification[4] = new TeacherEducationalQualification();
teacher.teacherEducationalQualification[4].NameOfDegree= "xyz";
// Or in a different way with the help of a local variable
var qualification;
qualification = new TeacherEducationalQualification();
qualification.NameOfDegree= "abc";
// set other fields
teacher.teacherEducationalQualification[0] = qualification;
// ...
qualification = new TeacherEducationalQualification();
qualification.NameOfDegree= "xyz";
// set other fields
teacher.teacherEducationalQualification[4] = qualification; // last item
Note: field names in C# should be camelCase - start with a lowercase letter
public string nameOfDegree;
Properties, on the other hand, should be PascalCase - start with an uppercase letter
public string NameOfDegree { get; set; } // auto-implemented property
When you instantiate an array you are essentially creating a data structure which is capable of holding a number of objects next to each other, however the objects (i.e., the array elements) must be instantiated separately. When an array is created, all elements of the array are initialised with the default value of the array type. For example for an array of integers all elements would be 0, for an array of DateTime all elements would be DateTime.MinValue and for an array of any reference type (like your example above) the elements will be null. That's why you got a NullReferenceException. If you like to instantiate an array as well as all elements using the default constructor you can use the following:
teacher.teacherEducationalQualification = new TeacherEducationalQualification[5];
for(int i = 0; i < teacher.teacherEducationalQualification.Length; i++)
teacher.teacherEducationalQualification[i] = new TeacherEducationalQualification();
After that, it'll be safe to assign to properties of each array element. My answer above does not necessarily mean this is the best design to solve this problem though.
When you instantiate a array of objects in c# you instantiate an array with null values:
teacher.teacherEducationalQualification = new TeacherEducationalQualification[5];
equals to
teacher.teacherEducationalQualification = new TeacherEducationalQualification[]{null, null, null, null, null};
so
teacher.teacherEducationalQualification[1] == null
you must instantiate the object before use it:
teacher.teacherEducationalQualification[1] = new TeacherEducationalQualification();
teacher.teacherEducationalQualification[1].NameOfDegree= "abc"
Otherwise if you don't want to create instances of Object, you need to use struct:
public struct TeacherEducationalQualification{
public string NameOfDegree;
public string NameOfUniversity;
public int YearOfGraduation;
}

C# Using a struct

I am using Mono Develop For Android and would like some help with using an array of structs.
Here is my code:
public struct overlayItem
{
string stringTestString;
float floatLongitude;
float floatLatitude;
}
And when using this struct:
overlayItem[1] items;
items[0].stringTestString = "test";
items[0].floatLongitude = 174.813213f;
items[0].floatLatitude = -41.228162f;
items[1].stringTestString = "test1";
items[1].floatLongitude = 170.813213f;
items[1].floatLatitude = -45.228162f;
I am getting the following error at the line:
overlayItem[1] items;
Unexpected symbol 'items'
Can I please have some help to correctly create an array of the above struct and then populate it with data.
Thanks
Define your struct like:
overlayItem[] items = new overlayItem[2];
Also you need to define your fields in the struct as public, to be able to access them outside the struct
public struct overlayItem
{
public string stringTestString;
public float floatLongitude;
public float floatLatitude;
}
(you may use Pascal case for your structure name)
You need to create your struct array like so:
overlayItem[] items = new overlayItem[2];
Remember to declare it with [2] as it will have 2 elements, not 1! Indexing an array might start at zero, but defining an array size does not.
Your sample code shows you need two items, so you need to declare the array of structs with length 2. This can be done with:
overlayItem[] items = new overlayItem[2];
The right way to declare the struct array for two elements is
overlayItem[] items = new overlayItem[2];
If you do not know the exact no of items you can also use list.
List<overlayItem> items = new List<overlayItem>();
items.Add( new overlayItem {
stringTestString = "test";
floatLongitude = 174.813213f;
floatLatitude = -41.228162f;
}
);

Syntax to add objects to a list?

I am trying to find out the syntax to add a complex object into a list. Here's what I know works:
ComplexObject temp = new ComplexObject() {attribute1 = 5, attribute2 = 6};
ComplexObjectList.Add(temp);
Here's what I'm wanting to do instead:
ComplexObjectList.Add(new ComplexObject(){attribute1 = 5, attribute2 = 6});
I realize that it doesn't work, but is there any other way to add one to my list without creating one before hand? I have no need for temp other than this one function call.
Assume you have this class (main point being must be an accessible constructor and the properties you wish to set must be visible):
public class Point
{
public int X { get; set; }
public int Y { get; set; }
}
And you have this list:
var listOfPoint = new List<Point>();
Then you can, as your second example ponders, do this:
listOfPoint.Add(new Point { X = 13, Y = 7 });
Which is roughly (there are some slight differences, Eric Lippert has some good reads on this) equivalent to your first example:
var temp = new Point { X = 13, Y = 7 };
listOfPoint.Add(temp);
In fact, you could add the point at the time the list is constructed as well:
var listOfPoint = new List<Point>
{
new Point { X = 7, Y = 13 }
};
Now the fact that you say you "realize that it doesn't work" is puzzling because your initializer syntax is correct, so I'm not sure if you're asking before trying it, or if there is an issue with the declaration of your list or your class that is throwing you off. That said, if your first code snippet compiled, technically so should your second.
Your code should work. If not, then the problem is probably in the declaration of ComplexObjectList.
Should be: List<ComplexObject> ComplexObjectList = new List<ComplexObject>();
Also make sure the class properties are public.

how to create multiple objects and enumerate them in c#

my problem is as follows:
Im building a console application which asks the user for the numbers of objects it should create and 4 variables that have to be assigned for every object.
The new objects name should contain a counting number starting from 1.
How would you solve this?
Im thinking about a class but im unsure about how to create the objects in runtime from userinput. Is a loop the best way to go?
What kind of class, struct, list, array .... would you recommend. The variables in the object are always the same type but i need to name them properly so I can effectivly write methods to perform operations on them in a later phase of the program.
Im just learning the language and I would be very thankful for a advice on how to approach my problem.
If I understand your problem correctly:
class MyClass
{
public int ObjectNumber { get; set; }
public string SomeVariable { get; set; }
public string AnotherVariable { get; set; }
}
// You should use keyboard input value for this
int objectsToCreate = 10;
// Create an array to hold all your objects
MyClass[] myObjects = new MyClass[objectsToCreate];
for (int i = 0; i < objectsToCreate; i++)
{
// Instantiate a new object, set it's number and
// some other properties
myObjects[i] = new MyClass()
{
ObjectNumber = i + 1,
SomeVariable = "SomeValue",
AnotherVariable = "AnotherValue"
};
}
This doesn't quite do what you described. Add in keyboard input and stuff :) Most of this code needs to be in some kind of Main method to actually run, etc.
In this case, I've chosen a class to hold your 4 variables. I have only implemented 3 though, and I've implemented them as properties, rather than fields. I'm not sure this is necessary for your assignment, but it is generally a good habit to not have publically accessible fields, and I don't want to be the one to teach you bad habits. See auto-implemented properties.
You mentioned a struct, which would be an option as well, depending on what you want to store in it. Generally though, a class would be a safer bet.
A loop would indeed be the way to go to initialize your objects. In this case, a for loop is most practical. It starts counting at 0, because we're putting the objects in an array, and array indexes in C# always start at 0. This means you have to use i + 1 to assign to the object number, or the objects would be numbered 0 - 9, just like their indexes in the array.
I'm initializing the objects using object initializer syntax, which is new in C# 3.0.
The old fashioned way would be to assign them one by one:
myObjects[i] = new MyClass();
myObjects[i].ObjectNumber = i + 1;
myObjects[i].SomeVariable = "SomeValue";
Alternatively, you could define a constructor for MyClass that takes 3 parameters.
One last thing: some people here posted answers which use a generic List (List<MyClass>) instead of an array. This will work fine, but in my example I chose to use the most basic form you could use. A List does not have a fixed size, unlike an array (notice how I initialized the array). Lists are great if you want to add more items later, or if you have no idea beforehand how many items you will need to store. However, in this case, we have the keyboard input, so we know exactly how many items we'll have. Thus: array. It will implicitly tell whoever is reading your code, that you do not intend to add more items later.
I hope this answered some questions, and raised some new ones. See just how deep the rabbit hole goes :P
Use a list or an array. List example:
int numberOfObjects = 3;
List<YourType> listOfObjects = new List<YourType>();
for(int i = 0 ; i < numberOfObjects ; i++ )
{
// Get input and create object ....
// Then add to your list
listOfObjects.Add(element);
}
Here, listOfObjects is a Generic list that can contain a variable number of objects of the type YourType. The list will automatically resize so it can hold the number of objects you add to it. Hope this helps.
If I understood what you are asking you could probably do something like this:
class Foo
{
private static int count;
public string name;
public Foo(...){
name = ++count + "";
}
}
I'm guessing what you're trying to do here, but this is a stab in the dark. The problem I'm having is dealing with the whole "the new objects name should contain a counting number starting from 1" thing. Anyway, here's my attempt:
public class UserInstantiatedClass
{
public int UserSetField1;
public int UserSetField2;
public int UserSetField3;
public int UserSetField4;
public string UserSpecifiedClassName;
}
public static class MyProgram
{
public static void Main(string [] args)
{
// gather user input, place into variables named
// numInstances, className, field1, field2, field3, field4
List<UserInstantiatedClass> instances = new List< UserInstantiatedClass>();
UserInstantiatedClass current = null;
for(int i=1; i<=numInstances; i++)
{
current = new UserInstantiatedClass();
current.UserSpecifiedClassName = className + i.ToString(); // adds the number 1, 2, 3, etc. to the class name specified
current.UserSetField1 = field1;
current.UserSetField2 = field2;
current.UserSetField3 = field3;
current.UserSetField4 = field4;
instances.Add(current);
}
// after this loop, the instances list contains the number of instances of the class UserInstantiatedClass specified by the numInstances variable.
}
}

Categories

Resources