Passing array between forms and managing in arrays - c#

I want to transfer an array from Form1 to Form2, then on Form2 add some values to the array.
On Form1 button click I put this code:
int[] arrayOfInt = new int[4];
arrayOfInt[0] = 19;
arrayOfInt[1] = 12;
Form2 frm2 = new Form2();
frm2.TakeThis(arrayOfInt);
frm2.Show();
In the form2 i created TakeThis(int[]) that catches the values from the form1 and display the values of the array on a label. Now, i cannot figure how to add some values to array. For example arrayOfInt[2] and arrayOfInt[3] and send to Form3.
Edit:
I decided to use a List to store my data but at the end I must convert a
list to an array because I am doing some reporting and math operations with the data.
This example is different from the example above. In this store all inputs from textboxs,comboxes in the list. At the end i need to convert the list into an array.
What have I done,
I created a new global class:
static class List{
static List<string> list;
public static void NewList(){
list=new List<string>();
}
public static void Save(string value){
list.Add(value);
}
public static void Display(){
foreach(var value in list){
MessageBox.Show(value);
}
}
}
The data is inserted between forms,
List.save(some_strings);
...
but at the end I need to convert the list in an array. I googled and I find the ToArray() function but i dont know how to use in my code. I tried with properties but i couldn't do the conversion. Please help.
Edit2
I found the solution.
In the global static class List I created a method that returns a List of strings:
public static List<string> GetList(){
return list;
}
Then, I created a new empty List of strings on Form2. Copied the old list to the new list and converted it in an array.
List<string> li=new List<string>();
li=List.GetList();
string[] temp=li.ToArray();

Don't use arrays if you want a data structure that you need to add items to.
Use a generic collection like List<T>.
In your case, a list of integers would be a List<int>.
IList<int> listOfInt = new List<int>();
listOfInt.Add(19);
listOfInt.Add(12);
Form2 frm2 = new Form2();
frm2.TakeThis(listOfInt);
frm2.Show();
When on Form2, your TakeThis function would look like this:
public voidTakeThis(IList<int> listOfInt)
{
listOfInt.Add(34);
}
This will also work when passing the list to another form, as List is a reference type whereas arrays are value types. If you don't know what this means, see this article.

Rather use ArrayList or even better IList<T>.
Arrays cannot be resized in C#

You will have to use ref argument on frm2.TakeThis() method:
Here is an MSDN article on it : Passing Arrays Using ref and out (C# Programming Guide).
void TakeThis(ref Int32[] array)
{
// Change array
}
and use like:
frm2.TakeThis(ref arrayOfInt);
Arrays need to passed by reference if you want to persist changes to them.
If you must not use an Array use a Collection like System.Collections.Generic.List<T>.

Use List<Int> and use oList.Add(item) method to add elements as array is Fixed in Lenght (you already giving it size at a time of initialization)
But if you want to use array at any cost then make a logic to create a new array upto the size of Old+ new added element and return that.
UPDATED
I believe you are facing problem because you have taken List of String instead or Int.
List<int> oIntList = new List<int>();
oIntList.Add(1);
oIntList.Add(3);
oIntList.Add(4);
oIntList.Add(5);
int[] oIntArr = oIntList.ToArray();

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.

Why do I get an error when List<object>.Add(int)

I have an array of List types:
List<object>[] vector = new List<object>[3];
The first List contains strings:
// Get word lists together, remove duplicates
var words = tableA.ToList().Union(tableB.ToList());
// Sort words
words = words.OrderBy(s => s, StringComparer.CurrentCultureIgnoreCase);
// Add words to the vector first slot
vector[0] = words.ToList<object>();
Now, I want to add ints to the second and third lists, but I get an error here:
vector[1].Add(tableA.GetValue(keyword));
vector[2].Add(tableB.GetValue(keyword));
GetValue() returns an int. But when I add these ints to the vector Lists it throws error:
ERROR Caught: Object reference not set to an instance of an object.
How should I add the ints to the List? Or is there some other data structure I should use instead for the vector? I feel there is some trivial cast I'm missing but I haven't been able find a solution.
I'm not an expert in C#, but i think i understand.
When you write :
List<object> vector = new List<object>[3];
you create a table of List with a size of 3.
You can put something into each slot of this array, but each "slot" still refers to no instance after this first line of code.
When you write
vector[0] = words.ToList<object>();
You put somehting into the first slot of vector list. But [1] and [2] are still empty. And
vector[1]
refers to a reference not set to an instance of an object. In short terms, it refers to nothing.
You must initialize each vector index value before add value. Thanks
When writing var a = new List<object> you´re only declaring that a is a list holding some (in your case three) items. However you don´t determine what stands in those three elements. You´d have to out some values into every single item, before you can anything with it (e.g. call any method).
You´re allready putting a list into the first item, however the elements on index one and two remain null causing a NullReferenceException when calling a method like the following:
vector[1].Add(...);
So you should initialize the value at index oe and two before:
vector[1] = new List<int>();
vector[2] = new List<int>();
But still you can´t do much with the list, because it is of type object, so you´d have to cast every element to the actual type:
((List<int>)vector[1]).Add(myInt);
Anyway I doubt storing three completely different lists within one single list alltogether is a good idea. Maybe you should define a class with the three lists as members instead:
class MyClass
{
public List<string> Words { get; set; }
public List<int> NumbersA { get; set; }
public List<int> NumbersB { get; set; }
}

Passing dynamic arrays into the argument

I have a class constructor accepting params T[][] arrays.
public CartesianProduct(params T[][] arrays)
{
}
I am passing the arrays below which is working fine
string[] arr1 = { "MSG1" };
string[] arr2 = { "OFFER1", "OFFER2" };
string[] arr3 = { "CTA1", "CTA2" };
var cross = new CartesianProduct<string>(arr1,arr2,arr3);
This works fine if i know the number of arrays and then pass it in the argument. The problem is when i am creating a button in the windows form to add new arrays. For example i have a simple text box and a button which creates an array. Click Add new array will create another array. How can i pass these arrays in the argument? Help would be appreciated . Thanks in advance
You can not dynamically add a 4th parameter to the call. You can dynamically create an array containing an arbitrary number of other arrays and pass that:
var aList = new List<string[]>();
aList.Add(arr1);
//...
var cross = new CartesianProduct<string>(aList.ToArray());
You may consider adding another constructor that accepts a List directly.

Check a value exist in array in unity 3d

I have two script.
Script1
Script2
In Script1 i declared a arraylist it contains value 2, 4, 6, etc...
public static ArrayList aArray= new ArrayList();
function update(){
if(bool1)
{
aArray.Add(i);
}
}
I have to check a value 5 exist in arraylist from Script2.
if value exists i have to get its key.
How to get it?
First, i would recommand using a generic List<T> instead of the non-generic ArrayList, which enables you to specify the type of objects that go into that list (for better type safety).
Also, declaring a variable readonly prevents you from accidently overwriting it, which is often the case with Lists (after all, you can always just Clear them):
public static readonly List<int> items = new List<int>();
Now to answer your actual question, if you want to check if a value exists in the list, you can use the method Contains.
To check if the value does not exist, just put an ! in front of the expression:
if (!Script1.items.Contains(i)) {
// This will only execute if the list does not contain i.
items.Add(i);
}
Try using Contains. This code will detect if you have already the value in the ArrayList and will stop code from adding it a second time.
public static ArrayList aArray= new ArrayList();
function update()
{
if(aArray.Contains(i)==false)
{
aArray.Add(i);
}
}
If you want to remove a value it is just as easy as aArray.Remove(i)
if I understood correctly, Script1 is in your camera, and Script2 is in a Character. For the sake of this example we'll call them MainCamera and Character respectively.
Now, unless I understood wrong, you're trying to access an Array in Script1 from Script2. While the other answers are very much correct, unity3D has a bit of a workaround needed to access it.
Anyway, within Script2 use this:
if(GameObject.Find("MainCamera").GetComponent<Script1>().aArray.Contains(5))
{
//Do your code here
}

Cannot implicitily convert type `double[]` to `System.Collections.Generic.List<double>`

I am getting the following error message with the code below. I thought the data type List<double> was the same as double[] but that C# required it to be instantiated using the first syntax for the variable to work as an object. What am I doing wrong or is my thinking wrong?
Cannot implicitily convert type `double[]` to `System.Collections.Generic.List<double>`
Code:
private void RunScript(List<Curve> crv, double nb, ref object DivPts)
{
List<double> nbtemp = new List<double>();
List<double> Divpt = new List<double>();
for(int i = 0; i < crv.Count;i = i + 2)
{
nbtemp = crv[i].DivideByLength(nb, true);
}
Divpt = nbtemp;
No, a list is not an array, even though the concepts are somewhat similar. The List<T> class in C# is actually implemented with a behind-the-scenes array.
If you want to set a List from an array, you can use something like this:
nbtemp = new List<double>(crv[i].DivideByLength(nb, true));
that will create a new List, and initialize it with the array. You can also use the AddRange method of the List, if you would like to append an array to an existing list, like this:
nbtemp.AddRange(crv[i].DivideByLength(nb, true));
You can't convert from Array to List, but you can easily call:
nbtemp = crv[i].DivideByLength(nb, true).ToList();
Or, since you already have to Lists defined, you could also:
nbtemp.AddRange(crv[i].DivideByLength(nb, true));
You are using an assignment and it is hard to tell what DivideByLength returns, if a single value then use:
nbtemp.Add(crv[i].DivideByLength(nb, true));
Otherwise, if it is returning an array, try changing your definition to allow the list to contain arrays:
List<double[]> nbtemp = new List<double[]>();
Note that List is not equivalent to double[]. List has many features that a simple array does not. You can see the differences by looking at the two different MSDN articles for which methods are publicly exposed.
List
Array
Also, your for loop as it stands is using an assignment. Without a change to that part of the code, you will only assign the last iteration of the for loop to the variable nbtemp (assuming you remove the error)
They are both IEnumerable implementers but they are not equivalent types. You will need to perform a cast or a method call. In the code above I would say you'd need:
nbtemp = (crv[i].DivideByLength(nb, true)).ToList();
or
nbtemp.AddRange(crv[i].DivideByLength(nb, true));

Categories

Resources