return single instance object as IEnumerable - c#

I have in instance of class foo and i want to return it as IEnumerable.
Can i do it without creating a new list etc..
Perhaps something like the following:
IEnumerable<foo>.fromInstance(foo)

Options:
Create an instance of a collection class, like an array or a list. This would be mutable by default, which would be slightly unhelpful if this is a sequence you want to be able to hand out in your API. You could create a ReadOnlyCollection<T> wrapper around such a collection though.
Write your own iterator block as per Botz3000's answer
Use Enumerable.Repeat(item, 1) from LINQ, if you're using .NET 3.5.
The best answer here depends on the usage. If you only need this to call another method which uses a sequence, and you know it won't be modified, I'd probably use an array. For example, in order to call Concat on some other sequence, you might want:
var wholeList = regularList.Concat(new[] { finalValue });
I have confidence that Concat isn't going to mutate the array, and nothing else will ever see the reference to the array itself.
If you need to return the sequence to some other code, and you don't know what it might do with it, I'd probably use Enumerable.Repeat.

you could do this:
public IEnumerable<Foo> GetSingleFooAsEnumerable() {
yield return singleFoo;
}

The best idiomatic way to do this is something like new[] { foo } which just creates a 1-element array of whatever type foo is declared to be.
The one possible downside to this is that arrays aren't immutable, so somebody can cast your IEnumerable<T> to a T[] and change the value in there. This is fairly unlikely, though, so I don't worry about it.

IENumerable is supposed to be used for something that you can enumerate through, so using it for a single instance seems quite strange. If you really need to, you can get it done like this. It might be a better way, but this should get the job done:
List<foo> myList = new List<foo>();
myList.Add( myInstanceOfFoo );
IEnumerable myEnumerable = myList.AsEnumerable();
Regardless of how you see this, you are actually trying to make a list of one element, and then it's really no reason to make it a list.

Related

Why does the Generic List AddRange return void instead of a list?

namespace System.Collections.Generic
public List<T>
public void AddRange(IEnumerable<T> collection)
It seems like it might be an intentional design decision not to return something. I got bitten by this expecting AddRange to be "fluent."
I was just curious if anyone knew of the design motivations, if there were any, to return nothing?
The AddRange method was added in .NET 2.0, before LINQ was out, and when "fluency" really wasn't in fashion at all. At the time, no one expected AddRange to return anything. Plus, in that version of .NET, there was no initializer for List object, so you had to Add() a bunch of items to the list. The AddRange provided a shortcut for not having to loop through and Add objects one by one.
The equivalent LINQ method is IEnumerable<T>.Concat()
The other answers are (essentially) correct, but none of them addresses both possibilities for why AddRange might return something.
One reason for doing that would be to create a fluent API, like this:
list.Add(1).Add(2).Add(3);
list.AddRange(aGroupOfNumbers).AddRange(theNextGroupOfNumbers);
To achieve this, the list simply returns itself at the end of the method that mutates the list. As Trisped notes, StringBuilder was doing this before the generic List<T> was introduced.
Another reason to return something, as Felix K. implies, is that the type is immutable. If a list is immutable, it can't return itself at the end of the method, because it can't mutate itself; and it can't return void, again, because it can't mutate itself. To reflect the change defined by the method contract, the list has to create a new instance that incorporates the change, and then, of course, it has to return that new instance to the caller. People sometimes have a hard time conceiving of that when it comes to collections, but there's a very well-known type that behaves this way: System.String. As d-b says, nobody expected the list to return anything, because the "classic" imperative programming style uses void methods when mutating data structures.
The designers of the System.Collections.Generic namespace may not have thought of giving their types a fluent API, but if they did, I could see how they might have decided against it. Certainly, the case for a fluent API in StringBuilder is somewhat stronger than the case for a fluent API in List<T>.
The list is not a struct so it mutates, if you want a list which avoids mutation you have to write your own or use Linq or just use this code:
List<T> newList = new List<T>(originalList);
newList.AddRange(...);
Or use Linq when constructing the list( IEnumerable<T>.Concat() at the constructor ). There are many ways to avoid mutation.
The AddRange method adds collection to the List<T> instance which called the function.
As a result you do not need to return anything, as the results are already there.
At the time if the work to be done did not create a new object then nothing was returned. The only exceptions which comes to mind is the StringBuilder class where most of the member methods which return a pointer to the calling instance. This was to enable command chaining and is specifically mentioned in the documentation.

List<T> exposed as IEnumerable<T>

I understand the hierarchy between the two and know how to convert between them, but is there anything fundamentally wrong with declaring a list like this?
IEnumerable<int> _bookmarkedDeals = new List<int>();
I don't need to change the list at any point, its either created or recreated as a whole.
As an alternative, possibly this
IEnumerable<int> _bookmarkedDeals = Enumerable.Empty<int>();
Well, in this case, _bookmarkedDeals will be empty so the declaration is somewhat useless. That being said, nothing wrong with treating a List as an IEnumerable.
(Unlike all answers here..) Yes. There is something very wrong with this declaration. You won't be able to use any of List<T> features without casting all the time back to list.
It's a good practice to return this type from your method if no list operations will be performed later on. But while you're in the same method - you're just making your life harder and less performant (because of the casts).
There is absolutely no problem with your declaration, although some people do like to declare the variable type precisely without any abstractization.
There is nothing wrong with that declaration but unless you have any specific restriction, IList<int> is a more appropiated interface for a list.
Nothing wrong.
If you never change the list in any way you could possibly use an array - it is slightly lighter than a list.
There's nothing fundamentally wrong with it, but why would you want to slice off some of the functionality that List provides (that IEnumerable doesn't)?
Nothing wrong with that, that's good design.
Have a read of Arrays Considered Somewhat Harmful.
Fabulous read about selecting the right interface.
No, there is nothing wrong with it.
If this is a local variable, I see no benefit over just using var to create a variable of type List<int>. If you are just enumerating, it does no harm at all though. If it is a field, perhaps event publicly exposed, it can be very sensible not to expose it as a List<int> or IList<int> to keep the free choice of concrete type.
There is no syntax problem but I don't see how it could be useful. If you don't insert any item in this row, this list is going to stay always empty unless you cast it back to List<int>, so why you want to declare it as IEnumerable<int>?

Can I have fixed typed ArrayList in C#, just like C++?

I have an ArrayList which contains fixed type of objects.
However everytime I need to extract an object a particular index, I need to typecast it to my user defined type from object type.
Is there a way in C# to declare ArrayList of fixed types just like Java and C++, or is there a work around to avoid the typecasting everytime?
Edit:
I apologize I forgot mentioning that I require the datastructure to be thread-safe, which List is not. Otherwise I would have just used a normal Array. But I want to save myself from the effort of explicitly locking and unlocking while writing the array.
So I thought of using ArrayList, synchronize it, but it requires typecasting every time.
You could use a List. The List class takes advantage of generics to make a strongly typed collection.
To use, just call new List< Type you want to use >() like this:
List<string> myStringList = new List<string>();
MSDN has a quick article on some ways you can make collections thread safe.
Take a look at System.Collections.Generic.List
http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx
Have you looked into SynchronizedCollection<T>? It is basically a thread-safe version of List<T>.
Note that this collection is part of System.ServiceModel, as it was added to support the channel dispatchers of WCF. It is a public collection that can be used by any code however, and is in the System.Collections.Generic namespace. All of its methods and its indexer are synchronized, so you would not have to manage locking yourself. Beware of LINQ, however, as the enumerator for this collection is not synchronized. You would need to lock on SyncRoot yourself if you wish to use the enumerator or use LINQ:
var syncList = new SynchronizedCollection<int>();
// ...
lock(syncList.SyncRoot)
{
var itemsInRange = syncList.Where(v => v > 100 && v < 1000);
}
Keep in mind, it uses hard locking (the lock keyword), and with many threads it will not be the most performant solution. If you have the option of using .NET 4.0, I would look into the new System.Collections.Concurrent namespace for some tasty new morsels like ConcurrentBag<T>.
Yes, but you need to use Generics. Look at the List class in the System.Collections.Generics namespace.
Generic Lists FTW!
var items = new List<someType>();
Use System.Collections.Generic.List<T>. If you want thread safe, simply lock the SyncRoot property in your operation.
Some code:
List<string> list = new List<string>();
lock (list.SyncRoot) {
list.Add("Hello World");
}
If you find every time to lock is annoying, you can override the List class and provide synchronized access on member functions.
If thread-safety is your concern then perhaps ConcurrentBag<T> would do the trick:
Represents a thread-safe, unordered collection of objects.
Note: This requires .NET 4.

Should I return an array or a collection from a function?

What's the preferred container type when returning multiple objects of the same type from a function?
Is it against good practice to return a simple array (like MyType[]), or should you wrap it in some generic container (like ICollection<MyType>)?
Thanks!
Eric Lippert has a good article on this. In case you can't be bothered to read the entire article, the answer is: return the interface.
Return an IEnumerable<T> using a yield return.
I would return an IList<T> as that gives the consumer of your function the greatest flexibility. That way if the consumer of your function only needed to enumerate the sequence they can do so, but if they want to use the sequence as a list they can do that as well.
My general rule of thumb is to accept the least restrictive type as a parameter and return the richest type I can. This is, of course, a balancing act as you don't want to lock yourself into any particular interface or implementation (but always, always try to use an interface).
This is the least presumptuous approach that you, the API developer, can take. It is not up to you to decide how a consumer of your function will use what they send you - that is why you would return an IList<T> in this case as to give them the greatest flexibility. Also for this same reason you would never presume to know what type of parameter a consumer will send you. If you only need to iterate a sequence sent to you as a parameter then make the parameter an IEnumerable<T> rather than a List<T>.
EDIT (monoxide): Since it doesn't look like the question is going to be closed, I just want to add a link from the other question about this: Why arrays are harmful
Why not List<T>?
From the Eric Lippert post mentioned by others, I thought I will highlight this:
If I need a sequence I’ll use
IEnumerable<T>, if I need a mapping
from contiguous numbers to data I’ll
use a List<T>, if I need a mapping
across arbitrary data I’ll use a
Dictionary<K,V>, if I need a set I’ll
use a HashSet<T>. I simply don’t need
arrays for anything, so I almost never
use them. They don’t solve a problem I
have better than the other tools at my
disposal.
A good piece of advice that I've oft heard quoted is this:
Be liberal in what you accept, precise in what you provide.
In terms of designing your API, I'd suggest you should be returning an Interface, not a concrete type.
Taking your example method, I'd rewrite it as follows:
public IList<object> Foo()
{
List<object> retList = new List<object>();
// Blah, blah, [snip]
return retList;
}
The key is that your internal implementation choice - to use a List - isn't revealed to the caller, but you're returning an appropriate interface.
Microsoft's own guidelines on framework development recommend against returning specific types, favoring interfaces. (Sorry, I couldn't find a link for this)
Similarly, your parameters should be as general as possible - instead of accepting an array, accept an IEnumerable of the appropriate type. This is compatible with arrays as well as lists and other useful types.
Taking your example method again:
public IList<object> Foo(IEnumerable<object> bar)
{
List<object> retList = new List<object>();
// Blah, blah, [snip]
return retList;
}
If the collection that is being returned is read-only, meaning you never want the elements to in the collection to be changed, then use IEnumerable<T>. This is the most basic representation of a read-only sequence of immutable (at least from the perspective of the enumeration itself) elements.
If you want it to be a self-contained collection that can be changed, then use ICollection<T> or IList<T>.
For example, if you wanted to return the results of searching for a particular set of files, then return IEnumerable<FileInfo>.
However, if you wanted to expose the files in a directory, however, you would expose IList/ICollection<FileInfo> as it makes sense that you would want to possibly change the contents of the collection.
return ICollection<type>
The advantage to generic return types, is that you can change the underlying implementation without changing the code that uses it. The advantage to returning the specific type, is you can use more type specific methods.
Always return an interface type that presents the greatest amount of functionality to the caller. So in your case ICollection<YourType> ought to be used.
Something interesting to note is that the BCL developers actually got this wrong in some place of the .NET framework - see this Eric Lippert blog post for that story.
Why not IList<MyType>?
It supports direct indexing which is hallmark for an array without removing the possibility to return a List<MyType> some day. If you want to suppress this feature, you probably want to return IEnumerable<MyType>.
It depends on what you plan to do with the collection you're returning. If you're just iterating, or if you only want the user to iterate, then I agree with #Daniel, return IEnumerable<T>. If you actually want to allow list-based operations, however, I'd return IList<T>.
Use generics. It's easier to interoperate with other collections classes and the type system is more able to help you with potential errors.
The old style of returning an array was a crutch before generics.
What ever makes your code more readable, maintainable and easier for YOU.
I would have used the simple array, simpler==better most of the time.
Although I really have to see the context to give the right answer.
There are big advantages to favouring IEnumerable over anything else, as this gives you the greatest implementation flexibility and allows you to use yield return or Linq operators for lazy implementation.
If the caller wants a List<T> instead they can simply call ToList() on whatever you returned, and the overall performance will be roughly the same as if you had created and returned a new List<T> from your method.
Array is harmful, but ICollection<T> is also harmful.
ICollection<T> cannot guarantee the object will be immutable.
My recommendation is to wrap the returning object with ReadOnlyCollection<T>

Are methods that modify reference type parameters bad?

I've seen methods like this:
public void Foo(List<string> list)
{
list.Add("Bar");
}
Is this good practice to modify parameters in a method?
Wouldn't this be better?
public List<string> Foo(List<string> list)
{
// Edit
List<string> newlist = new List<string>(list);
newlist.Add("Bar");
return newlist;
}
It just feels like the first example has unexpected side effects.
In the example you've given, the first seems a lot nicer to me than the second. If I saw a method that accepted a list and also returned a list, my first assumption would be that it was returning a new list and not touching the one it was given. The second method, therefore, is the one with unexpected side effects.
As long as your methods are named appropriately there's little danger in modifying the parameter. Consider this:
public void Fill<T>(IList<T> list)
{
// add a bunch of items to list
}
With a name like "Fill" you can be pretty certain that the method will modify the list.
Frankly, in this case, both methods do more or less the same thing. Both will modify the List that was passed in.
If the objective is to have lists immutable by such a method, the second example should make a copy of the List that was sent in, and then perform the Add operation on the new List and then return that.
I'm not familiar with C# nor .NET, so my guess would be something along the line of:
public List<string> Foo(List<string> list)
{
List<string> newList = (List<string>)list.Clone();
newList.Add("Bar");
return newList;
}
This way, the method which calls the Foo method will get the newly created List returned, and the original List that was passed in would not be touched.
This really is up to the "contract" of your specifications or API, so in cases where Lists can just be modified, I don't see a problem with going with the first approach.
You're doing the exact same thing in both methods, just one of them is returning the same list.
It really depends on what you're doing, in my opinion. Just make sure your documentation is clear on what is going on. Write pre-conditions and post-conditions if you're into that sort of thing.
It's actually not that unexpected that a method that takes a list as parameter modifies the list. If you want a method that only reads from the list, you would use an interface that only allows reading:
public int GetLongest(IEnumerable<string> list) {
int len = 0;
foreach (string s in list) {
len = Math.Max(len, s.Length);
}
return len;
}
By using an interface like this you don't only prohibit the method from changing the list, it also gets more flexible as it can use any collection that implements the interface, like a string array for example.
Some other languages has a const keyword that can be applied to parameters to prohibit a method from changing them. As .NET has interfaces that you can use for this and strings that are immutable, there isn't really a need for const parameters.
The advent of extension methods has made it a bit easier to deal with methods that introduce side effects. For example, in your example it becomes much more intuitive to say
public static class Extensions
{
public static void AddBar(this List<string> list)
{
list.Add("Bar");
}
}
and call it with
mylist.AddBar();
which makes it clearer that something is happening to the list.
As mentioned in the comments, this is most useful on lists since modifications to a list can tend to be more confusing. On a simple object, I would tend to just to modify the object in place.

Categories

Resources