How to convert ArrayList to an array of structure? - c#

Here I have:
Public Structure MyStruct
Public Name as String
Public Content as String
End Structure
Dim oStruct as MyStruct = New MyStruct()
oStruct.Name = ...
oStruct.Content = ...
Dim alList as ArrayList = new ArrayList()
alList.Add(oStruct)
I'd like to convert the ArrayList to a static strongly-typed Array of type MyStruct. How can I do that? I had no luck with ToArray.
I am using .NET Framework 2.0.

You have to cast the result of ToArray
MyStruct[] structs = (MyStruct[]) alList.ToArray(typeof(MyStruct));

I assume that since you are using ArrayList, you are using 1.1?
In which case, I suspect the following would work:
ArrayList list = new ArrayList();
MyStruct[] array = new MyStruct[list.Count];
list.CopyTo(array);
(edit - Bill's ToArray usage is more convenient - I didn't know about that one, but then, I very rarely [if ever] use ArrayList)
However, if MyStruct really is a struct, then I cannot say strongly enough that mutable structs are a bad idea - i.e. where you can set .Name and .Content after creation. Structs should almost always be immutable. In reality, your MyStruct looks like it should be a class. Also - I'm not "up" on VB, but are they public fields? Again - not recommended - properties would be preferable. I don't know about VB, but C# 3.0 has some very terse syntax for this:
public class SomeType
{
public string Name {get;set;}
public string Content {get;set;}
}
If you are using 2.0 or above, consider List<T> instead of ArrayList.

ToArray is the right way to go. In C# it would be:
MyStruct[] array = (MyStruct[]) alList.ToArray(typeof(MyStruct));
Are you stuck using 1.1, btw? If you're using 2.0, can you shift to List<T> instead?

This worked for me
Dim array As MyStruct() = alList.ToArray(GetType(MyStruct))

If you are running Visual Studio 2008 you can use a List object.
Dim alList As New List(Of MyStruct)
alList.Add(oStruct)

In case you're using 2.0 or later, you might want to define your arraylist like this:
Dim alList as New List(Of MyStruct)()
alList.Add(oStruct)
This will give you the same semantics as an array (lookup by index, strong typing, IEnumerable support, etc).
There are only two reasons in .Net 2.0 and later to use an array instead of a generic list:
You know with absolute certainty the number of items you have, and know that the count won't change. This is surprisingly rare.
You need to call a function that requires an array. There are still a fair number of these lurking in the BCL, but your own code should be asking for IEnumerable<T>, IList<T>, or ICollection<T>, and only rarely an array.
Finally, this is kind of nit-picky, but there are two stylistic points I want to address in the code you posted. First, note the abbreviated syntax I used to create the New List<MyStruct>. There's no = symbol and you don't have to key in the type name twice. That was support back in 1.1 as well, so there's no excuse there. Secondly, the style guidelines for .Net published by Microsoft on MSDN (see the general naming conventions section) specifically recommend against hungarian warts like 'o' or 'a'. It was nice for VB6/VBScript, which were loosely typed, but .Net is strongly typed, making the warts, well, wart-ugly.

Related

A const list in C#

I would like to create a list in C# that after its creation I won't be able to add or remove items from it. For example, I will create the list;
List<int> lst = a;
(a is an existing list), but after I won't be able to write the code (it will mark it as an error):
lst.Add(2);
.NET supports truly immutable collections, read-only views of mutable collections, and read-only interfaces implemented by mutable collections.
One such immutable collection is ImmutableArray<> which you can create as a.ToImmutableArray() in your example. Make sure to take a look at the other options MSDN lists because you may be better served by a different immutable collection. If you want to make copies of the original sequence with slight modifications, ImmutableList<> might be faster, for instance (the array is cheaper to create and access, though). Note that a.Add(...); is valid, but returns a new collection rather than changing a. If you have resharper, that will warn you if you ignore the return value of a pure method like Add (and there may be a roslyn extension to do something similar I'm unaware of). If you're going this route - consider skipping List<> entirely and going straight to immutable collections.
Read-only views of mutable collections are a little less safe but supported on older versions of .NET. The wrapping type is called ReadOnlyCollection<>, which in your example you might construct as a.AsReadOnly(). This collection does not guarantee immutability; it only guarrantees you can't change it. Some other bit of code that shares a reference to the underlying List<> can still change it. Also, ReadOnlyCollection also imposes some additional overhead; so you may not be winning much by avoiding immutable collections for performance reasons (TODO: benchmark this claim). You can use a read-only wrapper such as this even in a public API safely - there's no (non-reflection) way of getting the underlying list. However, since it's often no faster than immutable collections, and it's also not entirely safe, I recommend to avoid ReadOnlyCollection<> - I never use this anymore, personally.
Read-only interfaces implemented by mutable collections are even further down the scale of safety, but fast. You can simply cast List<> as IReadOnlyList<>, which you might do in your example as IReadOnlyList<int> lst = a. This is my preferences for internal code - you still get static type safety, you're simply not protected from malicious code or code that uses type-checks and casts unwisely (but those are avoidable via code-reviews in my experience). I've never been bitten by this choice, but it is less safe than the above two options. On the upside, it incurs no allocations and is faster. If you commonly do this, you may want to define an extension method to do the upcast for you (casts can be unsafe in C# because they not only do safe upcasts, but possibly failing downcasts, and user-defined conversions - so it's a good idea to avoid explicit casts wherever you can).
Note that in all cases, only the sequence itself is read-only. Underlying objects aren't affected (e.g. an int or string are immutable, but more complicated objects may or may not be).
TL;DR:
For safety: Use a.ToImmutableArray() to create an immutable copy in an ImmutableArray<int>.
For performance: Use IReadOnlyList<int> to help prevent accidental mutation in internal code with minimal performance overhead. Be aware that somebody can cast it back to List<> (don't do that), making this less "safe" for a public api.
Avoid a.AsReadOnly() which creates a ReadOnlyCollection<int> unless you're working on a legacy code base that doesn't support the newer alternatives, or if you really know what you're doing and have special needs (e.g. really do want to mutate the list elsewhere and have a read-only view).
You can use ImmutableList<T> / ImmutableArray<T> from System.Collections.Immutable NuGet:
var immutable = ImmutableList<int>.Create(1, 2, 3);
Or using the ToImmutableList extension method:
var immutable = mutableList.ToImmutableList();
In-case Add is invoked, *a new copy * is returned and doesn't modify the original list. This won't cause a compile time error though.
You need a ReadonlyCollection. You can create one from a list by calling List.AsReadOnly()
Reference: https://msdn.microsoft.com/en-us/library/ms132474.aspx
Why not just use an IEnumerable?
IEnumerable<string> myList = new List<string> { "value1", "value2" };
I recommend using a System.Collections.Immutable.ImmutableList<T> instance but referenced by a variable or property of type System.Collections.Generic.IReadOnlyList<T>. If you just use a naked immutable list, you won't get errors for adding to it, as you desire.
System.Collections.Generic.IReadOnlyList<int> list = a.ToImmutableList();
As an alternative to the already posted answers, you can wrap a readonly regular List<T> into an object that exposes it as IReadOnlyList.
class ROList<T>
{
public ROList(IEnumerable<T> argEnumerable)
{
m_list = new List<T>(argEnumerable);
}
private readonly List<T> m_list;
public IReadOnlyList<T> List { get { return m_list; } }
}
void Main()
{
var list = new List<int> {1, 2, 3};
var rolist = new ROList<int>(list);
foreach(var i in rolist.List)
Console.WriteLine(i);
//rolist.List.Add(4); // Uncomment this and it won't compile: Add() is not allowed
}
Your best bet here is to use an IReadOnlyList<int>.
The advantage of using IReadOnlyList<int> compared to List.AsReadOnly() is that a ReadOnlyCollection<T> can be assigned to an IList<T>, which can then be accessed via a writable indexer.
Example to clarify:
var original = new List<int> { 1, 2, 3 };
IReadOnlyList<int> readOnlyList = original;
Console.WriteLine(readOnlyList[0]); // Compiles.
readOnlyList[0] = 0; // Does not compile.
var readOnlyCollection = original.AsReadOnly();
readOnlyCollection[0] = 1; // Does not compile.
IList<int> collection = readOnlyCollection; // Compiles.
collection[0] = 1; // Compiles, but throws runtime exception.
Using an IReadOnlyList<int> avoids the possibility of accidentally passing the read-only list to a method which accepts an IList<> and which then tries to change an element - which would result in a runtime exception.
It could be IReadOnlyList<int>, e.g.
IReadOnlyList<int> lst = a;
So the initial list (a) is mutable while lst is not. Often we use IReadOnlyList<T> for public properties and IList<T> for private ones, e.g.
public class MyClass {
// class itself can modify m_MyList
private IList<int> m_MyList = new List{1, 2, 3};
...
// ... while code outside can't
public IReadOnlyList<int> MyList {
get {
return m_MyList;
}
}
}
Why not just:
readonly IEnumerable<int> lst = new List<int>() { a }

Does ArrayList in C# can contain objects various types?

Is it possible, to do something like that:
ArrayList arl = new ArrayList();
arl.Add(1);
arl.Add("test");
int[,] tab = new int[4, 4];
init(tab);
arl.Add(tab);
Is it possible to contain objects of various types (Like in JavaScript or Lua)? (C#)
Yes, ArrayList contains elements of type object so this means you can put everything in it. When retrieving it again, you can then case it back to its original type.
Of course, due to this casting it's less efficient.
Yes it is possible. ArrayList stores a collection of the type object meaning you can insert any .NET type.
You should really use List<T>. For example:
List<int> listIntegers = new List<int>();
listIntegers.Add(1);
You could also use List<object> however you will have to unbox all of the items in the list. Which potentially may incur performance issues.
You can have diffent types in a ArrayList
try this:
var ary = new ArrayList();
ary.Add("some string");
ary.Add(23.4);
ary.Add(new StringBuilder());
ary.Add("some other string");
You can then query it like this:
string[] strings = ary.OfType<string>();
StringBuilder[] stringBuilders = ary.OfType<StringBuilder>();
As for your question, yes ArrayList can contain various object types. It is generally recommended by Microsoft to use List<T> instead, to prevent the need of boxing and unboxing to Type object when using the same types.
If you have a recurring pattern of types it might be more helpful (and faster) to define a custom class:
protected class arl_items
{
public string item1 {get; set;};
public int item2 {get; set;};
public int[4,4] item3 {get; set;};
}
and then go:
List<arl_items> arl = new List<arl_items>();
But if there is no pattern to your value-types you can as well use ArrayList, because creating List<object> would be meaningless, as they are the same.
Just btw. i prefer using List<object> over ArrayList, but that is only my personal preference
Yes it can since it does not do any type checking, it can sometimes be faster than a List<T> when working with reference types, though it is generally not recommended to use it when you have a perfectly fine type safe alternative.
Any type that inherits from object can be stored in an ArrayList. Whenever you access an item in an ArrayList you must be careful to cast it to the correct type or else you will get a compiler error.
I believe ArrayList is an old relic from the days before generic types in .Net

Is it possible to define a local struct, within a method, in C#?

One of the common programming best practices is "define variables as close to where they are used as possible".
I use structs frequently to create code thats almost self documenting in places. However, C# forces me to define the struct outside the method. This breaks the aforementioned best practice - its basically creating an unwanted global variable type for the entire class.
Is it possible to define a local struct inside a method, just like a local variable, and if not, could you give me a window into the reasons the C# designers decided to prevent this?
Use Case
I'm converting part of a spreadsheet into C# code. I'd like to use local structs within the method to store temporary information in an organized manner, without having to resort to hundreds of separate variables that are global in scope.
Update 2016-August: C# 7.0 may have this feature!
As of 2016-Aug, apparently, this will be a feature in C# 7.0.
So the C# compiler team agreed - wow!
Update 2020-July: Now supported by C# and C++
C++ has always fully supported this. And it's fantastic.
C# 7.0 now has value tuples for a lightweight data structure with named fields. See answer from Ghost4Man.
I believe it's not permitted to define named types within a method. As to why, I'll have to speculate. If a type is not going to be used outside, then its existence probably cannot be justified.
You can however define anonymous type variables within a method. It will somewhat resembles structures. A compromise.
public void SomeMethod ()
{
var anonymousTypeVar = new { x = 5, y = 10 };
}
It is a little late but this is my solution for lists - using anonymous vars as the structs inside of methods:
var list = new[] { new { sn = "a1", sd = "b1" } }.ToList(); // declaring structure
list.Clear(); // clearing dummy element
list.Add(new { sn="a", sd="b"}); // adding real element
foreach (var leaf in list) if (leaf.sn == "a") break; // using it
Anonymous elements (sn and sd) are somehow read only.
Since C# 7.0, you can use value tuples if you want a lightweight data structure with named fields. They can be used not only locally inside methods, but also in parameters, returns, properties, fields, etc. You can use local functions to somewhat emulate struct methods.
var book = (id: 65, pageCount: 535); // Initialization A
(int id, int pageCount) book2 = (44, 100); // Initialization B
Console.WriteLine($"Book {book.id} has {book.pageCount} pages.");
(int id, int pageCount) = book; // Deconstruction into variables
Console.WriteLine($"Book {id} has {pageCount} pages.");
Here book is of type System.ValueTuple<int, int> (a generic struct).
You could do something like this using anonymous types. MSDN examples below:
var v = new { Amount = 108, Message = "Hello" };
or
var productQuery =
from prod in products
select new { prod.Color, prod.Price };
foreach (var v in productQuery)
{
Console.WriteLine("Color={0}, Price={1}", v.Color, v.Price);
}
Nowadays, you could also use a named tuple: https://learn.microsoft.com/en-us/dotnet/csharp/tuples
No, this is not possible. If you are using .net 4.0, you could use Tuple<T1, ..., Tn> to replicate such a thing.
I don't see the reason why you would need such a struct - just use variables with speaking names and this shouldn't be any problem at all. In combination with explicit declaration using the class names there is very little space for ambiguity.
You can define an anonymous type within your method and use it. The anonymous type will be readonly, so it gets you the immutability that is desired of structs. It will not explicitly be a struct, but it will be fully defined and contained within your method.
var myLocalType = new
{
SomeValue = "Foo",
SomeId = 14
};
it's not a struct, but mayme a var can help you out here?
var person = new {Name= "John", City = "London"};
it's strong typed so it will be compile time checked
You can create a dynamic type in c# 4.0 to accomplish this task, but its not exactly what you are looking for.
However I believe that the maximum of defining variables as close to where they are used is meant to mean where a variable is introduced into program flow not where the type is declared. I believe that most types have some ability to be reused creating in method types limits you ability to create reusable blocks of code that operates on common data.

Can I have a Untyped Collection in C#

I am porting some Java code to C# and I ran across this:
List<?>
As I understand it this is a List of type Unknown. As a result I can dictate the type elsewhere (at runtime? I'm not sure).
What is the fundamental equivalent in C#?
I think the best match to Java's List<?> would be C# 4.0 IEnumerable<out T> If you have a method that takes List<?> than you can call it with List<Object> and List<String> like so:
List<Object> objList = new List<Object>();
List<String> strList = new List<String>();
doSomething(objList); //OK
doSomething(strList); //OK
public void doSomething(List<?> theList) {
///Iterate through list
}
C# 4.0 IEnumerable<T> interface is actually IEnumerable<out T>, which means that if, say, R derives from T, IEnumerable<T> can be assigned to from IEnumerable<R>.
So, all you have to do is make your doSomething into DoSomething and have accept IEnumerable<T> parameter:
List<Object> objList = new List<Object>();
List<String> strList = new List<String>();
DoSomething(objList); //OK
DoSomething(strList); //OK
public void DoSomething<T>(IEnumerable<T> theList) {
///Iterate through list
}
EDIT: If C# 4.0 is not available, you can always fall back to either untyped IEnumerable or IList.
If you want a list that can hold anything, you can use a List<object> or an ArrayList.
If you want a strongly-typed list that holds an unknown type, you should make a generic class or method and use a List<T>.
For more specific advice, please provide more detail.
Firstly, as mentioned elsewhere, the unbounded wildcard parameterized type is not the same as Object. Generics are not covariant. So in the OP's Java example List<?> is not the same as List<Object>. As an example,
// Unbounded wildcard type is not the same as Object...
List<?> unboundedList = new ArrayList<Object>();
List<Object> objectList = new ArrayList<Object>();
unboundedList = objectList; // no problems
objectList = unboundedList; // whoops! compile time error
The only real use case for List<?> in Java is when interacting with legacy non generic collections. It allows you to avoid unchecked conversion warnings from the compiler.
C# does not have this use case. C# generics were not implemented using erasure. There is no backwards compatibility between the generic and non-generic collections in .net - they co-exist in the core .net libraries. That is different from Java where the generic version of the collections api replaced the non generic version at JDK 1.5.
So I don't think there is a reason to want this construct in C#, and there is no direct equivalent that behaves in the same way.
It sounds like IList is what you're looking for. It's a generic interface for lists, meaning you'll have to cast anything that comes out and be careful what you put in.
You could just use
List<object>
I think the questioner wants to convert something like this
int size2(List<?> list)
{
return 2*list.size();
}
List<Foo> list = ...
size2(list);
into C# equivalent.
The following code won't work, because it only accept List<Object>, not List<Foo>
int size2(List<Object> list)
{
return 2*list.size();
}

Simple form of Array class and Enum.GetValues()

I am working with the static method
Enum.GetValues(typeof(SomeEnum));
This method works great when all you need to do is enumerate the values, but for some reason it returns a very simple form of the Array class. I am trying to find an easy way to turn it's return value into a more "normal" collection class like a regular array or List<>.
So far if I want to do that I have to enumerate through the output of Enum.GetValues(typeof(SomeEnum)); and add them one by one to a List<>.
Any ideas how to do this more cleanly?
Answer:
The key is to cast the return result --
SomeEnum[] enums = (SomeEnum[]) Enum.GetValues(typeof(SomeEnum));
If you need a List then jus wrap it in parenthesis and ToList it like so:
List<SomeEnum> list = ((SomeEnum[]) Enum.GetValues(typeof(SomeEnum))).ToList();
If you're using .NET 3.5, you can also use Cast<T> and ToList extension methods.
IEnumerable<SomeEnum> enums = Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>();
You can also get a list if you want to
List<SomeEnum> list = Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>().ToList();
Inspired by Jon Skeet's unconstrained-melody, I came up with version I like more:
public static class Enum<T>
where T: struct
{
static Enum()
{
Trace.Assert(typeof(T).IsEnum);
Values = Array.AsReadOnly((T[])Enum.GetValues(typeof(T)));
}
public static readonly ReadOnlyCollection<T> Values;
}
and usage:
var values = Enum<BindingFlags>.Values;
Good thing is this version works faster for multiple calls because it does not create new array on every time.
I found here you can just do this:
SomeEnum[] enums = (SomeEnum[]) Enum.GetValues(typeof(SomeEnum));
And if you need a List just use .ToList() at the end, like this:
List<SomeEnum> list = ((SomeEnum[]) Enum.GetValues(typeof(SomeEnum))).ToList();
Or if you like this better:
List<SomeEnum> list2 = new List<SomeEnum>((SomeEnum[]) Enum.GetValues(typeof(SomeEnum)));
I have a brand new library (UnconstrainedMelody) which helps with this. It can return the values in a strongly typed array or in an immutable list:
SomeEnum[] array = Enums<SomeEnum>.GetValuesArray()
IList<SomeEnum> list = Enums<SomeEnum>.GetValues();
It's generic and has a constraint on the type parameter to make sure it's genuinely an enum. This isn't possible in normal C#, but the library does a bit of furtling to make it work. I like the second form more, because we cache the list - the fact that it's immutable means we can return the same reference again and again.
There are various other utility methods to make it easier to work with flags enums etc.
Enjoy.
This should work:
List<MyEnum> enums = ((MyEnum[])Enum.GetValues(typeof(MyEnum))).ToList();
The reason ToList() didn't work in the solution you posted in your question was that you're missing a set of parens around the casted portion. Hope this helps!
REVISION (12-Sep-2009 ~2:20 PM EST):
So, I made this suggestion last night on the basis that Enum.GetValues returns an Array, and I thought that Array implements IEnumerable<T>:
I believe you can construct a
List<T> passing any IEnumerable<T>
as a parameter into the constructor.
So you should be able to just do this:
List<SomeEnum> values = new List<SomeEnum>(Enum.GetValues(typeof(SomeEnum)));
However, GordonG quite promptly replied to my answer indicating that it doesn't compile. (Ordinarily I would test my answer, but I was at a computer without any development tools at the time and was also feeling quite [unreasonably] sure of myself.)
After some downvotes and heavy soul-searching I resolved to get to the bottom of this matter (after a good night's sleep). Turns out, according to Microsoft's documentation on the Array class here, that Array does implement IEnumerable<T>, but only at run time (so, not at compile time--hence the failure to compile). This, in hindsight, makes sense: Enum.GetValues is not a generic method, and so it cannot know what sort of generic collection to return beforehand. (At least that's how I understand it.)
Anyway, what this all means is that you can legally cast an Array to an IEnumerable<T> provided that you get your type right. And so, at last I can present my final answer, which is really the same as my original answer but with a simple cast thrown in to make everything legal:
// splitting into two lines just for readability's sake
List<SomeEnum> values;
values = new List<SomeEnum>((IEnumerable<T>) Enum.GetValues(typeof(SomeEnum)));
Of course, in retrospect, GordonG wasn't dead set on getting a List<T>, which means his own answer of casting to SomeEnum[] is really just as good.
Updated solution (from 'Konstantin Spirin') for .NET framework 2.0:
public static class Enum<T> where T : struct
{
static Enum()
{
Trace.Assert(typeof(T).IsEnum);
}
public static ReadOnlyCollection<T> Values = new ReadOnlyCollection<T>(((T[])Enum.GetValues(typeof(T))));
}
How about this:
List<SomeEnum> list = new List<SomeEnum>();
foreach (SomeEnum value in Enum.GetValues (typeof (SomeEnum)))
{
if (condition)
list.Add(value);
}

Categories