Is there a version of null but for list? - c#

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.

Related

redundant 'IEnumerable.OfType<T>' call consider comparing with 'null' instead

I'm getting this message from ReSharper. ReSharper is not proposing the change that I think would be appropriate after examining the code. As a result I am concerned that the problem might might be my not understanding what's going on instead of ReSharper not being as helpful as it could be.
public interface IFrobable { }
public class DataClass
{
public List<IFrobable> Frobables {get; set;}
//...
}
public class WorkerClass
{
//...
void Frobinate(List<IFrobable> frobables)
{
//Frobs the input
}
void DoSomething(List<IFrobable> input>)
{
//Original code with Resharper on OfType<IActivity>
Frobinate(input.OfType<IFrobable>().ToList());
//Suggested change from ReSharper - Is this a generic refactor
//instead of issue specific?
Frobinate(Enumerable.OfType<IFrobable>(input).ToList());
//What I think should be safe to do - compiles and appears to work
Frobinate(input);
}
}
Is there any reason why my proposed change might not be safe.
This is a regular function call:
Enumerable.OfType<IFrobable>(input)
This is the same function but invoked as an extension method:
input.OfType<IFrobable>()
In your case:
Frobinate(input);
Is absolutely fine because:
input.OfType<IFrobable>().ToList()
Equals to:
input.Where(x => x as IFrobable != null).ToList()
And in you method input is already defined as List<IFrobable> so what's the point?
Your last case may or may not introduce a logic error.
Do you really want Frobinate the ability to modify the input list passed into DoSomething or just a copy of those references?
//Suggested change from ReSharper
Actually, invoking OfType as a static method on Enumerable rather than as an extension method on input is not a suggestion from ReSharper - it's a context action. I expound on the difference in this post.
To the actual issue:
The inspection
Redundant 'IEnumerable.OfType<T>' call. Consider comparing with 'null' instead
is not one that ReSharper offers a quick fix solution with, I guess since there isn't a single unambiguously 'correct' change to make. It's just saying
hey, everything in input is definitely going to be of type IFrobable - if you're trying to filter this list you might have meant to be filtering by nullness instead
This probably isn't relevant in your case.
As to your proposed fix - as already noted, this will mean passing the actual List<> reference given to DoSomething to Frobinate, rather than a new List<> containing the same items - if this is OK, then go for it.
in your example you have input which already consists of elements of type IFrobable so ReSharper says that it doesn't make sense to filter them by type IFrobable because the filter condition is always true it proposes you to use just input.ToList() invocation or to filter elements buy nullness: input.Where(element => element != null).ToList()

Replace object but keep previous memory location in c#

Let's say I have a list:
List<object> list = new List();
list.Add(object1);
list.Add(object2);
object foo = list[0];
How do I make a call to list to replace list[0] such that foo will automatically point to the newly replaced object?
I know this line won't do the trick as foo will continue pointing to the old value of list[0]...
list[0] = object3;
Thanks!
It's not possible in my opinion. You need an additonal level of indirection which you have to implement yourself.
You could use a delegate/ anonymous lambda that fetches list[0]:
Func<object> foo = () => list[0];
Of course that changes the syntax slightly since it's now foo() instead of foo but it has the effect that you can fetch the value of list[0] at any time later and it always gets the current value.
What you really want to be able to do is to override the assignment operator but that's not possible in C#. The closest you'll get is to create a class that behaves a bit like Nullable<T> having a .Value property on it and assign to that .Value property instead of overwriting the object itself in the list.
You can use the fixed keyword but only in unsafe code. But i'm not sure what your attempting to do so it may not suite your needs if you need this level of control c++ cli would be a better choice.
Unsafe pointers are one possibility: http://msdn.microsoft.com/en-us/library/y31yhkeb(v=vs.80).aspx
For "safe" code, you can do something like store your value in an array of length 1, and then only store references to the array and always access the value by array[0], but this is a bit of a hack and there is probably a better way to do what you want to accomplish.

Sort list by property/anonymous function?

I've got a list defined like this...
var sets = new List<HashSet<int>>(numSets);
Why isn't there an overload so I can sort it like this?
sets.Sort(s => s.Count);
I want the largest set first. What's the easiest way to do that?
Because List<T> class was introduced in .NET 2.0 and the designers of this class decided so. You could use the OrderByDescending extension method:
sets = sets.OrderByDescending(s => s.Count).ToList();
Try this:
sets.Sort((setA, setB) => setB.Count.CompareTo(setA.Count));
This uses the Sort(Comparison<T> comparison) overload of List<T>.Sort.
The fact that the expression compares B with A rather than A with B is what produces the descending-by-count order that you require.
The reason your code doesn't work is because List<T>.Sort, unlike Enumerable.OrderByDescending, does not have an overload that accepts a Func<TSource, TKey> key-selector.
#Darin Dimitrov's technique of using OrderByDescending is fine too, but note that this will create a sorted list out of place and reassign the reference you have to the original list to the new, sorted one.

Convert Dictionary<MyType>.ValueCollection to IList<MyType>

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;

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