Accessing array element inside ArrayList c# - c#

I have the following problem,
When i am trying to access data from an Array inside another Array List, it dispalys that "cannot apply indexing[] with to an expression of type 'object'".
This is my code
public void getWaypoints() {
ArrayList potentialWPs = new ArrayList();
potentialWPs.Add(containerWaypoint.GetComponentInChildren(typeof(Transform)));
wayPoints = new ArrayList();
foreach (Transform potentialWP in potentialWPs){
if(potentialWP.transform != containerWaypoint.transform){
wayPoints[wayPoints.Count] = new ArrayList(2);
wayPoints[wayPoints.Count][0] = potentialWP;
}
}
The error are shown in the line "wayPoints[wayPoints.Count][0]".
Any one have any idea why this error is occurred?

Since ArrayList is a non-generic collection class, all items retrieved from it are objects, and need to be cast to their real types, like this:
foreach (Transform potentialWP in potentialWPs){
if(potentialWP.transform != containerWaypoint.transform){
wayPoints[wayPoints.Count] = new ArrayList(2);
ArrayList arr = wayPoints[wayPoint.Count] as ArrayList; <-- THIS
arr[0] = potentialWP;
}
Several important things to note:
1) This would have been simpelr if you had simply created the new array and held a reference to it (the arr variable I introduced) and then used that to add to the wayPoints and to assign to.
2) ArrayList really is an old and primitve class. Is there a reason you don't use a List<Transform> instead>?
3) You have a bug in your code, since you're access the ArayList in position Count. An ArrayList of length 2, if accessed at position 2, will crash - ArrayLists are 0-based, so you need to use Count - 1 to access the last position (1) on a length 2 array.

Try this wayPoints[0] = potentialWP;
Since you have already declared an array list with size wayPoints.Count , you have to mention the index correctly.

An ArrayList only holds object types; that why you get
"cannot apply indexing[] with to an expression of type 'object'"
You need to cast
wayPoints
to your desired type
EDIT:
You should be using
List<T> (System.Collections.Generics)

wayPoints[wayPoints.Count] = new ArrayList(2);
wayPoints[wayPoints.Count][0] = potentialWP;
wayPoints[wayPoints.Count] returns an object. You need to cast it, before treating it like an ArrayList:
((ArrayList)wayPoints[wayPoints.Count])[0] = potentialWP;
However, you shouldn't use ArrayList, as it's deprecated. Use List instead.

The main problem you have is that by using ArrayList which is just a collection of objects, there is no implicit conversion to an array. As others have answered, one way is to cast the result to an array, after which you can access it by index.
A better way, might be to use a Generic List<T> which can be defined as a list of lists:
List<List<Transform>> waypoints = new List<List<Transform>>();
This would make your code a lot easier:
public void getWaypoints() {
ArrayList potentialWPs = new ArrayList();
potentialWPs.Add(containerWaypoint.GetComponentInChildren(typeof(Transform)));
List<Transform[]> waypoints = new List<Transform[]>();
foreach (Transform potentialWP in potentialWPs){
if(potentialWP.transform != containerWaypoint.transform){
wayPoints.Add( new List<Transform>>(){ potentialWP });
}
}
}
waypoints is now a "multi-dimensional" list of lists of Transform. You can access any element like so
List<Transform> first = waypoints[0];
or you could access a Transform directly
Transform firstOfFirst = waypoints[0][0];
or you could add another Transform to an existing list
waypoints[0].Add(anotherTransform);

Related

Public List error when setting up a table view in Visual Studio

I'm trying to work on a table view in Xcode and Visual studio, and am setting it up to import data, but I keep getting an error in the List.
using System.Collections.Generic;
using AppKit;
namespace HCATester
{
public class NormsLogDataSource : NSTableViewDataSource
{
public NormsLogDataSource(){}
public List Norms = new List();
public override nint GetRowCount(NSTableView tableView)
{
return Norms.Count;
}
}
}
Whenever I select it to see what's wrong, this is what I get:
Implements the System.Collections.Generic.IList interface. The size of a List is dynamically increased as required. A List is not guaranteed to be sorted. It is the programmer's responsibility to sort the List prior to performing operations (such as BinarySearch) that require a List to be sorted. Indexing operations are required to perform in constant access time; that is, O(1).
Your problem is with the declaration of your List. You are using the System.Collections.Generic namespace which (among other collections) contains the generic List<T>. But you aren't specifying the generic type parameter.
You see, before we had generics, we used ArrayList which just held a collection of objects, so we'd always need to cast it to what we actually wanted. For example, if we want a ArrayList of integers we could declare our list like this:
ArrayList list = new ArrayList();
list.Add(1);
list.Add(2);
list.Add(3);
But when using it we would need to cast our item from object to whatever type we wanted like so:
int item1 = (int) list[0];
int item2 = (int) list[1];
// ...
This gets confusing and error prone, for example if a Method takes an ArrayList as a parameter you'd always need to make sure every element of said ArrayList was of the right type.
In come Generics and the generic List<T>, with it we can define a strongly typed List. The same example as above but using List is much easier to read and understand:
List<int> list = new List<int>();
list.Add(1);
list.Add(1);
list.Add(1);
int item1 = list[0];
int item2 = list[1];
// ...
Now we don't need to cast our object, as we already know what datatype it is. This also adds a lot more security, as we can define what types are valid inside a List.
Now to answer your question, you need to specify the datatype you are using, you said string so I'll show you how. All you need to do is replace your line where you are declaring the List with this:
public List<string> Norms = new List<string>();
P.S the generic () part of a class can be read as "of" or "for", e.g List<T> would be read as "A List of T", List<int> would be "A List of Integers". And ViewModel<TView> would be read as "A ViewModel for TView"

Is this call-by-reference?

I have an ArrayList:
ArrayList ReceivedPackets = new ArrayList();
And I have another ArrayList:
ArrayList returnList = ReceivedPackets;
Why does returnList loose it's value when I run this code?
ArrayList ReceivedPackets = new ArrayList(); // ReceivedPackets is empty
ReceivedPackets.Add(1); // Now it has an Integer
ArrayList returnList = ReceivedPackets; // Call-by-Reference (I thought), returnList now has an Integer
ReceivedPackets.clear(); // returnList is empty now. Why?
When you do this:
ArrayList returnList = ReceivedPackets;
You are creating a new variable called returnList, but this variable points to the same in-memory object as ReceivedPackets. There is still only one actual ArrayList, it just has two variables pointing to it. So changes made to one are reflected in both.
How can I do without returnList loosing it's value?
Create a new object. At its simplest, that would look like this:
ArrayList returnList = new ArrayList();
If you also want that object to contain all the values from ReceivedPackets, fortunately ArrayList has a constructor overload which does just that:
ArrayList returnList = new ArrayList(ReceivedPackets);
Now you'd have two objects which should contain copies of the same data. Changes to one would not be reflected in the other.
In the absence of that constructor, ArrayList also has some CopyTo() methods which can be used to copy elements from one to the other. Failing that, you could also manually loop over the source ArrayList and copy elements to the destination ArrayList.
It's possible that this can get pretty confusing if the ArrayList itself contains reference objects. Because those too may have multiple "pointers" to the same in-memory object.
For example, if you create a single Widget object and add it to two ArrayList objects, then any modifications made to the ArrayList objects (adding/removing elements) would be independent, but any modification made to the Widget object would be reflected in both ArrayLists.
The point is that the ArrayList itself is an object, independent of the objects it contains.
So, depending on the full context of what you're doing, your mileage may vary.
ArrayList is a reference type, meaning that if you simply assign some variable to an instance of it, both objects will point to the same location in memory.
If you want to create deep copy, create a new object.
static void Main() {
ArrayList a = new ArrayList() {1,2,3};
var b = a;
var c = new ArrayList(a);
a.Clear();
Console.WriteLine(a.Count); // 0
Console.WriteLine(b.Count); // 0
Console.WriteLine(c.Count); // 3
}

Access object property in array

class Program{
static void Main(string[] args){
object[] array = new object[1];
CreateItem item = new CreateItem();
item.name = "Necklace";
item.value = 5;
array[0] = item;
Console.WriteLine(array[0].name); //This part of the code doesn't work.
//It can't find the property name.
Console.ReadLine();
}
}
public class CreateItem {
public string name;
public int value;
}
Hi there! First of all I'd like to say that I'm not very familiar with objects, so excuse any mistakes you can see in the code (Although feel free to correct them, it'd be a great way to learn).
I've been working on making a small game using C#, but I came across a problem: I can't access my object properties when I put them in an array. Does anyone know which code I should use to be able to access my object properties while they're in an array?
Thanks for reading, and once again, excuse any silly mistakes I made, I'm fairly new to working with objects.
You shouldn't use an object array when you have a strong type that you're interested in using (and you know the type already).
CreateItem[] array = new CreateItem[1];
CreateItem item = new CreateItem();
item.name = "Necklace";
item.value = 5;
array[0] = item;
Console.WriteLine(array[0].name);
Necklace will now be outputted as expected.
You should probably look at using Generics and Lists, it is a very common and a valuable concept to grasp, as is the concept of Boxing and Unboxing which Generics solves.
class Program{
static void Main(string[] args){
List<CreateItem> list = new List<CreateItem>();
CreateItem item = new CreateItem();
item.name = "Necklace";
item.value = 5;
list.Add( item );
Console.WriteLine(list[0].name); //This part of the code doesn't work.
//It can't find the property name.
Console.ReadLine();
}
}
You could cast the object to your type, i.e.:
Console.WriteLine(((CreateItem)array[0]).name);
or (more effectively)
define your array as CreateItem[] array = new CreateItem[1];
Line
object[] array = new object[1];
creates an array of elements of type Object which is the base class for all other classes in .NET.
When you do:
array[n] = item;
an implicit conversion to the base type occurs and through array[n] you can access only members of the Object type portion of the CreateItem object (like ToString() or GetType() - their overrides will be called).
If you want to access entire CreateItem object, you have to cast the reference to the base type back to the original type, by using cast operator for example:
var name = ((CreateItem)array[0]).name;
This explicit casting is error-prone, has a run-time overhead and it is a sign of the poor design. When you know the type of the collection in advance, declare the collection of that type as other answers are suggesting:
// you can use array if you know number of items in advance and that number of elements will not change
CreateItem[] array = new CreateItem[N];
// use list if number of elements might change
List<CreateItem> list = new List<CreateItem>();

Store variables in list/array and loop through later c#

Sorry, I think I was not clear earlier. I am trying to do as O.R.mapper says below- create a list of arbitrary variables and then get their values later in foreach loop.
Moreover, all variables are of string type so I think can come in one list. Thanks.
Is there a way to store variables in a list or array then then loop through them later.
For example: I have three variables in a class c named x,y and Z.
can I do something like:
public List Max_One = new List {c.x,c.y,c.z}
and then later in the code
foreach (string var in Max_One)
{
if ((var < 0) | (var > 1 ))
{
// some code here
}
}
Is there a particular reason why you want to store the list of variables beforehand? If it is sufficient to reuse such a list whenever you need it, I would opt for creating a property that returns an IEnumerable<string>:
public IEnumerable<string> Max_One {
get {
yield return c.x;
yield return c.y;
yield return c.z;
}
}
The values returned in this enumerable would be retrieved only when the property getter is invoked. Hence, the resulting enumerable would always contain the current values of c.x, c.y and c.z.
You can then iterate over these values with a foreach loop as alluded to by yourself in your question.
This might not be practical if you need to gradually assemble the list of variables; in that case, you might have to work with reflection. If this is really required, please let me know; I can provide an example for that, but it will become more verbose and complex.
Yes, e.g. if they are all strings:
public List<string> Max_One = new List<string> {c.x,c.y,c.z};
This uses the collection initializer syntax.
It doesn't make sense to compare a string to an int, though. This is a valid example:
foreach (string var in Max_One)
{
if (string.IsNullOrEmpty(var))
{
// some code here
}
}
If your properties are numbers (int, for example) you can do this:
List<int> Max_One = new List<int> { c.x, c.y, c.Z };
and use your foreach like this
foreach(int myNum in Max_One) { ... } //you can't name an iterator 'var', it's a reserved word
Replace int in list declaration with the correct numeric type (double, decimal, etc.)
You could try using:
List<object> list = new List<object>
{
c.x,
c.y,
c.z
};
I will answer your question in reverse way
To start with , you cannot name your variable with "var" since it is reserved name. So what you can do for the foreach is
foreach (var x in Max_One)
{
if ((x< 0) || (x> 1 ))
{
// some code here
}
}
if you have .Net 3.0 and later framework, you can use "var" to define x as a member of Max_One list without worrying about the actual type of x. if you have older than the version 3.0 then you need to specify the datatype of x, and in this case your code is valid (still risky though)
The last point (which is the your first point)
public List Max_One = new List {c.x,c.y,c.z}
There are main thing you need to know , that is in order to store in a list , the members must be from the same datatype, so unless a , b , and c are from the same datatype you cannot store them in the same list EXCEPT if you defined the list to store elements of datatype "object".
If you used the "Object" method, you need to cast the elements into the original type such as:
var x = (int) Max_One[0];
You can read more about lists and other alternatives from this website
http://www.dotnetperls.com/collections
P.s. if this is a homework, then you should read more and learn more from video tutorials and books ;)

How to get the data from list without using iterator in c#

i have a list contains set of strings, i want to fetch the data present in the list based on index, with out using iterator.. is there any functions like get() or getat() some sort of method using which we can fetch?
myList[index] is the way to go
List<string> myList = new List<string>();
myList.Add("string 1");
myList.Add("String 2");
Console.WriteLine(myList[0]); // string 1
Console.WriteLine(myList[1]); // String 2
List<string> myList = new List<string();
//add some elements to the list
//then get the third element
string thirdElement = myList[2];
You can just do:
item = list[i];
Use the overloaded index operator.
List<String> list; // ... initialize, populate list
String element = list[1]; // get the element at index 1
If your collection implements IList<T>, just use indexer. Otherwise, if your collection only allows forward-only access (that is, only implements IEnumerable<T>) you can use ElementAt() method, but it still uses iterator under the hood.
I don't know what kind of list you're talking about exactly, but most collections in .net have a CopyTo function, and you can access individual items with the [] operator.
List<string> list = new List<string>();
list.Add("lots of strings");
//If you want to print all the strings you can do:
foreach(string str in list)
Console.WriteLine(str);
//If you want to modify each string in the list, make each lower case for example,
// you can do. this is working by using the index of the elements in the list:
for(int i = 0; i < list.Count; i++)
list[i] = list[i].ToLower();
If you use the generic type List (or another implementation of IList) you can use the index operator to directly access items at certain positions: item = myList[3]
If you use a type that only implements IEnumerable you should use the ElementAt() function.
What's your reason to avoid the use of iterators?

Categories