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);
}
Related
I have a unit test that I am trying to write.
I have this section as part of a working version:
List<MyClass> queryResult = new List<MyClass>(){};
A.CallTo(() => _dataContext.GetAll<MyClass>()).Returns(queryResult.AsQueryable());
However, I would rather put something like "null" instead of "queryResult.AsQueryable()", Then there would be no need to create an empty list.
But GetAll will return a list empty or full by the looks of things. Therefore, null won't work.
Is there something like "List.Empty" that I can use instead?
Thanks
There are Array.Empty<T>() and Enumerable.Empty<T>() that might work for you. Neither of them allocates a new object per-call (they are both backed by a static T[] field on a generic class - EmptyArray<T>.Value or EmptyEnumerable<T>.Instance, although these are both implementation details)
You can use
Enumerable.Empty<MyClass>().ToList()
But I can not see any differences in this case.
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 }
That's a pretty elementary question, but I have never delved into generics before and I found myself in the need to use it. Unfortunately I don't have the time right now to go through any tutorials and the answers I found to related questions so far aren't what one could call basic, so there we go:
Let's say I have the following:
List<MyClass1> list1 = getListType1();
List<MyClass2> list2 = getListType2();
if (someCondition)
MyMethod(list1);
else
MyMethod(list2);
And of course
void MyMethod(List<T> list){
//Do stuff
}
Well, I thought it would be this simple, but apparently it is not. VS warns me that
The type arguments for method MyMethod(System.Collections.Generic.List) cannot be inferred from the usage
and if I compile it anyway, I get a
The type or namespace name 'T' could not be found
error.
In the many answers I found, I read that I have to declare what T is, which makes sense, but I couldn't quite grasp how to do so in such a simplistic scenario. Of course, those answers created even more questions in my mind, but right now I just want an explanation of what I'm doing wrong (besides not studying generics) and how to make it right.
You need to declare T against the method, then C# can identify the type the method is receiving. Try this:
void MyMethod<T>(List<T> list){
//Do stuff
}
Then call it by doing:
if (someCondition)
MyMethod(list1);
else
MyMethod(list2);
You can make it even stricter, if all classes you are going to pass to the method share a common base class:
void MyMethod<T>(List<T> list) where T : MyClassBase
You need to add the generic type parameter for T to your method:
void MyMethod<T>(List<T> list) {
The compiler doesn't know what T represents, otherwise.
You need to let c# know what type is sent:
List<MyClass1> list1 = getListType1();
List<MyClass2> list2 = getListType2();
if (someCondition)
MyMethod<MyClass1>(list1);
else
MyMethod<MyClass2>(list2);
void MyMethod<T>(List<T> list){
//Do stuff
}
Basically, In C#, List < T > class represents a strongly typed list of objects that can be accessed by index.
And it also supports storing values of a specific type without casting to or from object.
we can use in Interger value & String Value in the List.
I have tried many ways like
Cast<CustomObject>, as Customobject and ToArray(Customobject) but nothing worked.
How can I add List or ArrayList via AddRange to a CustomObject[] Array?
Code is really difficult.
But if you have some time you can get the complete source of the destination list from here:
http://www.codeproject.com/Articles/4012/C-List-View-v1-3?msg=3844172#xx3844172xx
This is a Custom Listview
I activated a combobox for the second column, so I can select diferrent values for a cell.
But before this, I have to add something to select.
This is the hole problem.
Update:
Firstly, thanks for the help !
Secondly, Found a solution in the comments from the website with the source.
Had to add some code and changed the destination custom array to a List
list.Cast<CustomObject>().ToArray()
Will work as long as the things in the list are actually CustomObject. If they might be other types, you can use OfType<CustomObject>() instead of Cast. This will filter out anything of an incompatible type.
Assuming the objects really are instances of CustomObject, use LINQ Select method:
objList.Select(o => o as CustomObject).ToArray();
Otherwise you will get an array of null.
If its a List<CustomObject> then let us say
CustomObject[] coarr = list_of_customobject.ToArray();
If its an ArrayList then
CustomObject[] coarr = arraylist.OfType<CustomObject>().ToArray();
If you are unsure whether all of your objects are of the type CustomObject try
var result = list.OfType<CustomObject>.ToArray();
Strictly speaking you cannot add elements to an array, since an array's length remains constant over its lifetime. There are two things you can do:
Create a new array
myArray = myTList.ToArray() // generic)
myArray = myArrayList.Cast<CustomObject>().ToArray() // cast, non-generic
myArray = myArrayList.OfType<CustomObject>().ToArray() // filter by type, non-generic
Set elements of an array
myArray[x] = myTList[y] // generic
myArray[x] = (CustomObject)myArrayList[y] // non-generic
I recommend you to take the generic collection whenever possible. They provide you additional type safety. Casting object variables cause runtime errors you could detect at compile time by using generic types.
If you actually want to add elements to an existing collection, you may try to use a dynamic collection type rather than an array: List<T> : IList<T> or LinkedList<T> : ICollection<T> are a good point to start, or maybe more specific types like Stack<T> or Queue<T>.
I'm using a Dictionary<int, MyType> in a class. That class implements a interface that requires an IList<MyType> to be returned. Is there a simple way to to cast the one to the other (without copying the entire thing)?
My current solution follows:
private IList<MyType> ConvertToList(Dictionary<int, MyType>.ValueCollection valueCollection)
{
List<MyType> list = new List<MyType>();
list.AddRange(valueCollection);
return list;
}
You'll need to do a copy, but this is probably a good thing. In C# 2, your current code is almost the cleanest you can make. It would be improved by directly constructing your list off your values (List<MyType> list = new List<MyType>(valueCollection);), but a copy will still be required.
Using LINQ with C# 3, however, you would be able to do:
myDictionary.Values.ToList();
That being said, I would not (probably) try to avoid the copy. Returning a copy of your values tends to be safer, since it prevents the caller from causing problems if they attempt to modify your collection. By returning a copy, the caller can do list.Add(...) or list.Remove(...) without causing your class problems.
Edit: Given your comment below, if all you want is an IEnumerable<T> with a Count, you can just return ICollection<T>. This is directly implemented by ValueCollection, which means you can just return your dictionary's values directly, with no copying:
private ICollection<MyType> ConvertToList(Dictionary<int, MyType>.ValueCollection valueCollection)
{
return valueCollection;
}
(Granted, this method becomes really useless in this case - but I wanted to demonstrate it for you...)
How about
Dictionary<int, MyType> dlist = new Dictionary<int, MyType>();
IList<MyType> list = new List<MyType>(dlist.Values);
This is not possible.
A dictionary (including its Values collection) is an inherently unordered collections; its order will change based on the hashcodes of its keys. This is why ValueCollection doesn't implement IList<T> in the first place.
If you really wanted to, you could make a wrapper class that implements IList and wraps the ValueCollection, using a foreach loop in the indexer. However, it's not a good idea.
You can use the constructor:
public IList<MyType> MyValues
{
get { return new List<MyType>(myDictionary.Values); }
}
(Edited to remove an assertion I'm not 100% sure on.)
You can use ToList() method:
myDictionary.Values.ToList();
It is available importing Linq: using System.Linq;