C#, API - Multidimensional arrays - c#

I have an unmanaged API function and below mentioned is it's equivalent c# code...
Myfunction(unit handle, int index, out bool flag,out int value, out string name);
Here the variable index varies from 0 to 59. I am able to fetch the data individually. I mean I can pass value to the variable index from a TextBox and I am getting the corresponding outputs. But how to collect the values in an array fashion. Each time I don't want to give index input I simply want to display all the values in a ListBox... How to achieve this?

Before we start, this is not a multidimensional array. This is a simple linear array with one index.
Create a struct to hold the values for one item:
struct MyItem
{
bool flag;
int value;
string name;
}
Then have a function return an array of these:
MyItem[] GetItems()
{
MyItem[] result = new MyItem[ItemCount];
// Populate result
return result;
}
Alternatively you might well store the data in a generic collection like List<MyItem>. Fundamentally the key is to creat a structure that can contain a single item, and then operate on collections of items.

Related

Assigning values to a list vs an array and ArgumentOutOfRangeException

Why does assigning values to a List have to be done with Add but to an array it can be done with the [] operator?
For example:
string[] y = new string[10];
y[0] = "asdf"; //fine
List<string> x = new List<string>(10);
x[0] = "asdf"; //ArgumentOutOfRangeException
Shouldn't both have the same behavior?
Taking a look at the source code for List(of T), your see that the indexed property getter/setters look like this:
// Sets or Gets the element at the given index.
//
public T this[int index] {
get {
// Fllowing trick can reduce the range check by one
if ((uint) index >= (uint)_size) {
ThrowHelper.ThrowArgumentOutOfRangeException();
}
return _items[index];
}
set {
if ((uint) index >= (uint)_size) {
ThrowHelper.ThrowArgumentOutOfRangeException();
}
_items[index] = value;
_version++;
}
}
Notice that, before setting the corresponding item in the List's internal array, it first checks the private _size variable to make sure it is in range. _size is not set to the size of the array, however. Size is incremented/decremented in the List's various Add/Remove methods, so even if you instantiate a list with an initial capacity of 10, that is the internal capacity of the List's array. Here is the constructor:
// Constructs a List with a given initial capacity. The list is
// initially empty, but will have room for the given number of elements
// before any reallocations are required.
//
public List(int capacity) {
if (capacity < 0) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity, ExceptionResource.ArgumentOutOfRange_SmallCapacity);
_items = new T[capacity];
}
The _size is not set (and therefore remains as its initialized value of 0) unless you either use Add/Remove/AddRange/etc. or use the constructor that accepts an IEnumerable (in which case the size because the number of items in the IEnumerable).
It makes sense if you think about it. The idea of a list is so that you DON'T have to worry about the complexity (and ugliness) of numeric indexes and resizing/copying arrays when the capacity needs to change. The size of the internal array, after the List is instantiated, should be of no concern to the developer. If you want to micromanage how the internal array is utilized, then you should either create your own implementation, or just use an array.
The way you implemented your array is right.
The size of an array needs to be declared when it is created. There is no way around that.
However, Lists' sizes are more flexible. You can add as many elements as you want without having to declare an initial size. After you've added elements however, you can access or edit them through their index number. Here's an example.
You are getting that exception because technically the list doesn't fill an index until you actually add a value to it. Let me know if that clears it up.
//You can add your elements when you instantiate it
List<string> names = new List<string>{"Alex", "Tommy", "Bob"};
//Or you can add them later
List<string> cities = new List<string>();
cities.Add("Denver");
cities.Add("New York");
//Now that they are created you can access or edit any of the elements within them.
names[2] = "Gerard";
cities[1] = "San Francisco";
The internal structure of a list is different of an array. While in a array you have a size of items defined on its definition, the amout of memory necessary to have these objects is realocate in memory by the CLR.
In a list<T> you can define the maximum of items in a list. That is (part of) the reason you have to call the Add method to add objects in a list<T>. You can define a initial Capacity for a list as you did on the constructor. If you need to add more than the capacity, the list will rearrange it for you. The framework manages for you how much items you have on the list.
Another important thing is that in both cases, you can access by index. For sample:
var obj = list[1];
var obj2 = array[1];
In a case that you do not have the 1 index on the list<T>/array, in an array, you get the default(T) (considering T as your type) and in a list you will get an Exception.
This constructor does not create any elements in list. It just reserves memory for items that could be added to this list.
You still have to insert items to the list manually before you can use then this way.
Upd:
This overload could help you when you dealing with large collections and you almost sure that you'll put about N items into your list. Thus you can reserve memory on creation and avoid memory allocation while you add items into this list (which could be slow sometimes).

Advantages of indexers over object array?

I read about indexers in MSDN - Indexers which explains how we can use objects like array with index i.e. just like normal Array. However, I think we can create array of objects like
point[] array = new point[100];
So what is the special advantages Indexer over object array?
If all you are after is a collection of objects then an indexer has absolutely no benefit over an array. However, if you need to store state as well as a collection, that's where an indexer shines.
For example, consider the following
public class Tree
{
private Branch[] branches = new Branch[100];
...
public string Name { get; set; }
public Branch this[int i]
{
get
{
return branches[i];
}
}
}
Tree holds an internal collection but also has state of it's own. Having an indexer property allows for simple access to the underlying collection e.g.
tree.Name = "Tree";
var branch = tree[0];
Not in this case that you have mentioned above. However, if you have anything that cannot be represented as an array will be a good example for Indexers to be used.
One .Net framework example is Dictionary. If you see the definition of Dictionary type in .Net you will find that they let you get an access of value through key. So that is a good example of using indexers where the index is presented as string.
Without indexers, how would you do that? of course by index value but it cannot be of type string then, will that be user friendly? I guess not!
So indexers gives you an opportunity to represent your code well.
Similarly, in case of point type, of course you can access the value of by index i.e. 0,1,2...99. What if you want to make more user friendly, such as point["x"]. That is where Indexers will help you.
Another example I could think of how about if you want to access your stack like s1 instead of push and s[0] instead of pop method.
There is a very good example of indexers by Microsoft where you can access file byte by byte by providing character location as index.
http://msdn.microsoft.com/en-us/library/aa288465(v=vs.71).aspx
In your line of code, you've defined an array of point objects, whatever those might be.
point[] array = new point[100];
Assuming you have direct access to the array, you can access the first element in your array like this:
var firstPoint = array[0];
The page you linked to is showing you how you could access that array, if it were defined inside your class, and you didn't have direct access to the array (since it's private).
For example, we could modify the example on that page to use your array:
class SampleCollection
{
private Point[] arr = new Point[100];
public Point this[int i]
{
get { return arr[i]; }
set { arr[i] = value; }
}
}
Then you could access the first element in the array like this:
var sc = new SampleCollection();
var item1 = sc[0];
That isn't an indexer.
An indexer is not used to create an array of objects, it is actually an operator overload to the '[]' operator.
An example for it's use would be if you wanted to make a List wrapper class.
In order to preserve the square braces functionality you would need (and want) to override the square braces operator. This is done via an indexer method.

how to get direct value from a list that contain an array in C#

how to get direct value from a list that contain an array ?
hey guys ,
i want to directly get a certain value from a list that contain an array
List<int[]> myList = new List<int[]>();
myList.Add( new int[2] { 10, 11 } );
its clear for me to get this using foreach loop like
foreach ( int[] p in mylist)
console.write(p[0]);
i do want to retrive this single data using expression like list[0] for list of integers
thanks..
Your question is very unclear, but if you know the array index within the array, you can use:
int value = myList[listIndex][arrayIndex];
Effectively this is just doing:
int[] array = myList[listIndex];
int value = array[arrayIndex];
im not entirely sure what you mean . . .
it would look like a 2d array: myList[position of array in list][position of item in selected array]. this is because a list is generic container and the overloaded bracket operator will return the specific type (which in this case is an array), that then enables you to use the bracket again to refer to the items contained in the array.
the snipplet you wrote actually only iterates the first item foreach array in your list (was this on purpose)?
in essence, you kind of need 2 pieces of information unless you only want the first item in each list (position 0) in which case you would create a new container class, implement the IList interface and overload the bracket operator like this:
public int this[int index]
{
get
{
return myList[index][0];
}
set
{
myList[index][0] = value;
}
}

how to pass a list of values in struct in c#

I know how to pass a list of values in arrays
int[] unit = new int[] {1,-3,3,4};
string[] letter_grade = new string[] {"a+","B","c","W"};
double totalGPA;
GPA get = new GPA();
get.getgpa(unit, letter_grade ,out totalGPA);
but i wanted to know how to pass it using structs i can send single value but not getting how to send list of values
double totalGPA;
GPA get = new GPA();
GPAList[] Val = new GPAList[1];
Val[0].grade ="d";
Val[0].unitgrade = 4;
get.getgpa(Val[0], out totalGPA);
You just pass the struct array Val to getgpa:
get.getgpa(Val, out totalGPA);
Then getgpa should accept a array of GPA structs:
void getgpa(GPA[] gpas, out double totalGPA)
As far as I've understood your question, you want to pass a collection of values using struct.
A struct is not meant for storing collections, for collections we've arrays, arraylist, hashtable etc in c#.
The purpose of a struct is to represent a complete information into a single datatype. Structures are simply lightweight classes, they are no way used for collections.
If you want to use structures for storing collection of values, then again you'll have to make array of structures.
If you want to pass array of a structure, then in the formal parameter list, you should expect array of that structure itself, for eg.
**get.getgpa(Val, out totalGPA);**
for above code to work, the signature of getgpa function should be:
**getgpa(GPA[] arr,out double totalGPA)**
Hope this helps.

Add ints to listview for sorting

I have a listview and I am trying to sort it based on a column. I have the columnclick event etc working, and it sorts, but I have the following problem:
I can't seem to add items to the listview as integers. This is a problem as if I have a column of ints that I had to use ToString() on, the sort puts 10 ahead of 2.
Does anyone know how I can add items as int's so that the sort has the desired functionality. Also, not all columns are int, there are some string columns and I'd like the sort to work on those too.
For reference, I used the following tutorial for the sort code: http://support.microsoft.com/kb/319401
Cheers
You can create a sorter class that implements IComparer and assign it to the ListViewItemSorter property of the ListView.
IComparer has a method Compare. Two ListViewItem instances are passed to that method. You need to read the column value, then parse it to int and return the correct comparison result (int based instead of string based).
You can create your own ListViewItem class that creates the string value for the column but also holds the original int value to avoid the int.Parse call in the comparer.
Untested example:
public class MyItemComparer : IComparer
{
public int Compare(object x, object y)
{
ListViewItem xItem = (ListViewItem)x;
ListViewItem yItem = (ListViewItem)y;
int a = int.Parse(xItem.SubItems[0]);
int b = int.Parse(yItem.SubItems[0]);
return a.CompareTo(b);
}
}
You can detect if the selected column has numbers.
Write this in the compare function
int intX = 0, intY = 0;
if(int.TryParse(listviewX.SubItems[ColumnToSort].Text, out intX)
&& int.TryParse(listviewY.SubItems[ColumnToSort].Text, out intY))
{
return intX.CompareTo(inty);
}
Maybe is problem if some column contains numbers and text.

Categories