Convert IList to array in C# - c#

I want to convert IList to array:
Please see my code:
IList list = new ArrayList();
list.Add(1);
Array array = new Array[list.Count];
list.CopyTo(array, 0);
Why I get System.InvalidCastException : At least one element in the source array could not be cast down to the destination array type? How that can be resolved assuming I can not use ArrayList as type for list variable ?
Update 1: I use .NET 1.1. So I can not use Generics, Linq and so on. I just want to receive result for the most common case - integer was given as example, I need this code works for all types so I use Array here (maybe I am wrong about using Array but I need, once again, common case).

You're creating an array of Array values. 1 is an int, not an Array. You should have:
IList list = new ArrayList();
list.Add(1);
Array array = new int[list.Count];
list.CopyTo(array, 0);
or, ideally, don't use the non-generic types to start with... use List instead of ArrayList, IList<T> instead of IList etc.
EDIT: Note that the third line could easily be:
Array array = new object[list.Count];
instead.

You can use Cast and ToArray:
Array array = list.Cast<int>().ToArray();

I'm surprised that
Array array = new Array[list.Count];
even compiles but it does not do what you want it to. Use
object[] array = new object[list.Count];
And, standard remark: if you can use C#3 or later, avoid ArrayList as much as possible. You'll probably be happier with a List<int>

probably the most compact solution is this:
Enumerable.Range(0, list.Count).Select(i => list[i]).ToArray();

Related

Vba Type-Statement conversion to C#

This can probably be accomplished very easily but I have the following statement in VBA:
Type testType
integerArray(5 To 100) As Double
End Type
How can I accomplish the same in C#?
#Edit 14:16 08-07-2015
In my belief this is not the same as the question mentioned. This is a question how to convert the Type statement with an array inside. The question mentioned is only about an array with it's starting index.
Actually C# does not support those kind of arrays based on any other start-index then zero.
However you may do.
double[] myArray = new double[96];
Alternatvily you may create a dictionary with indexes as keys and the actual value:
var myDict = new Dictionary<int, double>();

Does ToArray() from an array return itself? [duplicate]

This question already has answers here:
Does Array.ToArray<>() return the original array if it is the same type?
(2 answers)
Closed 7 years ago.
I just want to know if the implementation of LINQ protects the developer against performance hits when calling ToArray() from an Array.
For example,
var array1 = Enumerable.Range(0,short.MaxValue).ToArray(); //does the actual copy
var array2 = array1.ToArray() //is this the same object as array1?
var array3 = ((IEnumerable<int>)array2).ToArray() //what about this?
Do all three of these ToArray() calls have the same performance implications?
Other questions like this have addressed the general performance implications of ToArray(),
Is it better to call ToList() or ToArray() in LINQ queries?
Linq ToList/ToArray/ToDictionary performance
but I'm curious as to whether the implementation is "smart enough" to avoid copying elements to another array if the source is an array.
I printed all of the hash codes from array 1, 2, and 3.
Console.WriteLine(array1.GetHashCode());
Console.WriteLine(array2.GetHashCode());
Console.WriteLine(array3.GetHashCode());
and got
62476613
11404313
64923656
Since the hash codes are all different does that mean that a copy operation happened all three times?
Does ToArray() from an array return itself?
No it doesn't. It returns a new copy of the array with each element copied to the new array.
Do all three of these ToArray() calls have the same performance
implications?
The first one: Enumerable.Range(0,short.MaxValue).ToArray(); creates an array from IEnumerable<T>.
Second one: var array2 = array1.ToArray(), It will create a new array with each element copied to array2, so array1 and array2 will have different references.
Third one: var array3 = ((IEnumerable<int>)array2).ToArray() is just redundant code, since the array is already IEnumerable<int> so casting it to it will not make a difference.
Does ToArray() from an array return itself?
I will say no, beause of MSDN's own words:
Creates an array from a IEnumerable.
https://msdn.microsoft.com/en-us/library/vstudio/bb298736(v=vs.100).aspx

Comparing two lists and deleting identical results c#

I have two lists:
List<int> positionsThatCannotBeMovedTo =...
List<int> desiredLocations =...
I am trying to remove all of the positions which cannot be moved to from the desired locations to create a list of safe positions:
List<int> safePositions = new List<int>(uniquePositions);
safePositions.RemoveAll(positionsThatCannotBeMovedTo);
however it's throwing the error:
"Argument1: cannot convert from 'System.Collections.Generic.List' to 'System.Predicate'
I'm not entirely sure what this means or how I'm misusing the function. Is anybody able to explain this for me please? I am doing it this way because of the answer in this question:
Compare two lists for updates, deletions and additions
RemoveAll takes a Predicate<T>, but you are passing a list:
safePositions.RemoveAll(x => positionsThatCannotBeMovedTo.Contains(x));
There is another way to obtain a list with elements except the elements of another list
List<int> positionsThatCannotBeMovedTo = new List<int>() {1,2,3,4,5,6,7};
List<int> uniquePositions = new List<int>() {5,6,7,8,9,10};
List<int> safePosition = uniquePositions.Except(positionsThatCannotBeMovedTo).ToList();
MSDN on Enumerable<T>.Except
You could also accomplish this using the Except extension method. Assuming uniquePositions is your list of all your positions.
var safePositions = uniquePositions.Except(positionsThatCannotBeMovedTo).ToList();
Except is the set difference operator and as you are using lists of ints the default comparer is fine.

Array initialization in C#

In C#, the array can be initialized by the following syntax
string[]arr = {"text1","text2"}; // this works
why does the following not work
string[]arr1;
arr1={"phrase1","phrase2"};//Does not compile.
string[] arr = { "text1", "text2" };
This works because this is a special syntax only allowed when first initializing an array variable (personally I didn't even know it existed).
If you want to later assign a new array to a variable, you need to say new:
arr = new string[] { "text1", "text2" };
You can also say just new [] and the compiler will figure out the type for you.
The second syntax is wrong according to the C# specification:
http://msdn.microsoft.com/en-us/library/aa664573%28v=vs.71%29.aspx
Check that link as well for more examples about how to initialize an array:
All possible C# array initialization syntaxes
It's all about allocating memory.
The first is short for:
string[]arr = new string[]{"text1","text2"};
So the compiler knows in the same statement the number of elements to allocate using the new keyword.
The second is just wrong syntax.
If you want to do it in two steps:
string[]arr1; // defines array(pointer)
arr1=new string[]{"phrase1","phrase2"}; // again when `new` is used for dynamic memory allocation, the size is available.

C#: Is there a way to resize an array of unknown type using reflection?

My users pass me an array of some type, say int[] or string[]. I can easily query the types of the elements via GetElementType, and I can find out how long the array was when it was passed to me via GetRank, GetLength, etc.
The arrays are passed in a params list, so visualize code like this:
public void Resizer(params object[] objs)
{
foreach (object o in objs)
Array.Resize(ref o, 3);
}
What I would like to do is the converse of the Get methods that are available and that do work: I want to resize the array that was passed to me, setting the length to some other length (like 3 in this silly example).
I'm doing this because in my setting the array will contain data received from a set of cloud computing servers and we can't know how many will respond in advance, hence can't preallocate the array to have the right length. Ideally, in fact, my user passes in an array of length 0, and I pass back an array of length n, signifying that I got n replies from the servers that were queries.
I can't do this with Array.Resize(ref T, int) because I don't know T at compile time.
Is there a way to pull this off?
This should work:
static void Resize(ref Array array, int newSize) {
Type elementType = array.GetType().GetElementType();
Array newArray = Array.CreateInstance(elementType, newSize);
Array.Copy(array, newArray, Math.Min(array.Length, newArray.Length));
array = newArray;
}
Why not just create a new array of whichever type you need that is the size that you want? Then populate it from the array you want to resize, setting non existent values to some default.
In case anyone is curious, I ended up switching my code to use List
I agree with the comments that you should be using List(Of T), but if you want to copy your array into a new array of the same type, you could do something like the following.
// Your passed in array.
object[] objs = new object[5] {1,2,3,4,5};
// Create an array of the same type.
Array a = Array.CreateInstance(objs[0].GetType(), objs.Length+3);
// Copy in values.
objs.CopyTo(a,0);
I guess I'll just switch to using Lists, but this is a shame; the code will be quite a bit messier looking and since my users are basically at the level of first-semester ugrads, each little thing will make their lives less good. But I'm suspecting that you folks don't see a way to do this either. Oh well....

Categories