454

Is there a common way to pass a single item of type T to a method which expects an IEnumerable<T> parameter? Language is C#, framework version 2.0.

Currently I am using a helper method (it's .Net 2.0, so I have a whole bunch of casting/projecting helper methods similar to LINQ), but this just seems silly:

public static class IEnumerableExt
{
    // usage: IEnumerableExt.FromSingleItem(someObject);
    public static IEnumerable<T> FromSingleItem<T>(T item)
    {
        yield return item; 
    }
}

Other way would of course be to create and populate a List<T> or an Array and pass it instead of IEnumerable<T>.

[Edit] As an extension method it might be named:

public static class IEnumerableExt
{
    // usage: someObject.SingleItemAsEnumerable();
    public static IEnumerable<T> SingleItemAsEnumerable<T>(this T item)
    {
        yield return item; 
    }
}

Am I missing something here?

[Edit2] We found someObject.Yield() (as @Peter suggested in the comments below) to be the best name for this extension method, mainly for brevity, so here it is along with the XML comment if anyone wants to grab it:

public static class IEnumerableExt
{
    /// <summary>
    /// Wraps this object instance into an IEnumerable&lt;T&gt;
    /// consisting of a single item.
    /// </summary>
    /// <typeparam name="T"> Type of the object. </typeparam>
    /// <param name="item"> The instance that will be wrapped. </param>
    /// <returns> An IEnumerable&lt;T&gt; consisting of a single item. </returns>
    public static IEnumerable<T> Yield<T>(this T item)
    {
        yield return item;
    }
}
vgru
  • 49,838
  • 16
  • 120
  • 201
  • 7
    I would make a slight modification in the body of the extension method: `if (item == null) yield break;` Now you're stopped from passing null as well as taking advantage of the (trivial) null object pattern for `IEnumerable`. (`foreach (var x in xs)` handles an empty `xs` just fine). Incidentally, this function is the monadic unit for the list monad that is `IEnumerable`, and given the monad love-fest at Microsoft I'm surprised something like this isn't in the framework in the first place. – Matt Enright Nov 11 '09 at 12:49
  • Thanks for your comment. I do have a static `IEnumerableExt.Empty` property, however, which has only a `yield break;` statement inside, simply to avoid passing null as a parameter to my "single item" method. This also leaves the (improbable) option of returning a single null value from an `IEnumerable`, if needed. – vgru Nov 12 '09 at 09:12
  • In a near-duplicate (later) post [I added an answer](http://stackoverflow.com/questions/4890528/is-there-a-linq-method-to-add-a-single-item-to-an-ienumerablet/7688420#7688420) that, I think, very usefully exploits the `params` keyword in a way that is touched by some answers and comments here and is very similar to your 2nd method. It definitely is the shortest function I ever wrote! – Gert Arnold Oct 08 '11 at 09:31
  • 4
    For the extension method, you shouldn't name it `AsEnumerable` because a built-in extension with that name [already exists](http://msdn.microsoft.com/en-us/library/bb335435.aspx). (When `T` implements `IEnumerable`, e.g., `string`.) – Jon-Eric Aug 13 '12 at 16:12
  • 2
    @MattEnright the if (item == null) yield break can only be used if T is a class type. You would have to code it in a different and less efficient way. Something like if(T == default(T) && typeof(T).IsClass) yield break; – Thanasis Ioannidis Nov 04 '12 at 00:29
  • 2
    @Saysmaster Just because `item == null` doesn't ever return false for a value type doesn't mean that you can't use it - it's a perfectly legal statement with the intended semantics. – Matt Enright Nov 05 '12 at 16:33
  • 1
    @MattEnright You are right. For some odd reason I had been left with the impression that the compiler will throw an error when you try to compare a non-class object to null! Just tested it, and it seems it compiles successfully. – Thanasis Ioannidis Nov 06 '12 at 08:23
  • 26
    How about naming the method `Yield`? Nothing beats brevity. – Philip Guin Nov 19 '12 at 08:13
  • possible duplicate of [Favorite way to create an new IEnumerable sequence from a single value?](http://stackoverflow.com/questions/1019737/favorite-way-to-create-an-new-ienumerablet-sequence-from-a-single-value) – nawfal Feb 17 '13 at 12:21
  • @Saysmaster "compiles successfully" - but violates idiomatic C# assumptions. – Den Sep 26 '13 at 11:12
  • @MattEnright "it's a perfectly legal statement with the intended semantics" - singletons are also legal, but it's better to avoid them. Idiomatic C# implies that left side in 'left.right()' should not be null. – Den Sep 26 '13 at 11:14
  • @Den no arguments there :) But my point was firstly, about `left == null` where left is a value type (so the condition is trivially false), which doesn't hurt anything and makes sense when the type is unknown, and secondly that I think it's good principle to use null objects (like an empty sequence) instead of a literal null in the name of robustness, when something like that exists. – Matt Enright Sep 27 '13 at 15:22
  • 4
    Naming suggestions here. "SingleItemAsEnumerable" a bit verbose. "Yield" describes the implementation rather than interface - which is not good. For a better name, I suggest "AsSingleton", which correspond the exact meaning of the behaviour. – Earth Engine Mar 24 '14 at 01:40
  • 6
    I hate the `left==null` check here. It breaks the beauti of the code and stops the code being more flexable -- what if some day you turn out need to generate a singleton with something that can be null? I mean, `new T[] { null }` is not the same as `new T[] {}`, and some day you may need to distinguish them. – Earth Engine Mar 24 '14 at 01:45
  • I agree with both points made by @EarthEngine. – Jason Boyd Apr 10 '15 at 16:11
  • 1
    Why on earth do we think Yield is a good name? Yield what? Call it from what it does not how it works. Implementations change overtime whilst yielding the same results. – Alan Macdonald Jul 31 '15 at 14:05
  • 1
    How about naming the method `Once`? – Yurii N. Feb 07 '18 at 23:04
  • 1
    *if (item == null) yield break;* -- this is an extremely bad idea. The semantics of the method is to yield an enumeration of one item, and that one item might well be null. Having it yield 0 items when the item is null is a violation of the semantics and a dozen bugs waiting. *you're stopped from passing null* -- um, no, you're stopped from yielding null, which is a bad thing. *as well as taking advantage of the (trivial) null object pattern* -- this has nothing to do with the null object pattern, which is the use of a non-null object to represent nullity. – Jim Balter Nov 29 '18 at 07:01
  • 1
    *Why on earth do we think Yield is a good name?* -- because it obviously is. *Yield what?* -- the one item being provided. *Call it from what it does not how it works* -- Yield says nothing about how it works, just what it does. You don't have to implement it using yield return ... you can write it using a class that implements `IEnumerable`. The fact that `Yield` and `yield` are the same word because they have the same semantics; it has nothing to do with implementation. – Jim Balter Nov 29 '18 at 07:05
  • *How about naming the method Once* -- that's not a good name; the concept here is *one*, not *once*. – Jim Balter Nov 29 '18 at 07:06
  • 1
    *"Yield" describes the implementation rather than interface* -- no, it doesn't. *For a better name, I suggest "AsSingleton"* -- it's not a singleton as that term is used in computer science: https://en.wikipedia.org/wiki/Singleton_pattern – Jim Balter Nov 29 '18 at 07:10
  • 1
    *Just because item == null doesn't ever return false for a value type* -- it does return false for nullable value types, e.g., `int?`, i.e. `Nullable`. This is one of many confusions and errors in the comments here. – Jim Balter Nov 29 '18 at 07:16
  • I was trying to do the same thing, and `new T[] { item }` worked for me. I think case T will be name of my class from where i am calling it and item is an instance of that class. – Atta H. Apr 29 '19 at 20:25
  • This is where Java's `Optional` is superior to C# nullable IMO. It's essentially an enumerable with 0 or 1 item(s). It has all the `map`, `flatmap`, `filter` methods you'd expect. And you don't have to unwrap to a single item at the end. – wilmol Nov 11 '22 at 02:08

20 Answers20

196

Well, if the method expects an IEnumerable you've got to pass something that is a list, even if it contains one element only.

passing

new[] { item }

as the argument should be enough I think

OschtärEi
  • 2,255
  • 3
  • 20
  • 41
Mario F
  • 45,569
  • 6
  • 37
  • 38
144

In C# 3.0 you can utilize the System.Linq.Enumerable class:

// using System.Linq

Enumerable.Repeat(item, 1);

This will create a new IEnumerable that only contains your item.

luksan
  • 7,661
  • 3
  • 36
  • 38
  • 35
    I think that this solution will make the code harder to read. :( Repeat on a single element is quite counter-intuitive don't you think? – Drahakar Apr 10 '11 at 22:14
  • 8
    Repeat once reads ok to me. Far simpler solution without having to worry about adding yet another extension method, and ensuring the namespace is included wherever you want to use it. – si618 Apr 09 '13 at 02:20
  • 17
    Yeah I actually just use `new[]{ item }` myself, I just thought that was an interesting solution. – luksan Apr 09 '13 at 03:01
  • 8
    This solution is money. – ProVega Oct 11 '13 at 04:28
  • 3
    IMHO this should be the accepted answer. It's easy to read, concise, and it's implemented in a single line on the BCL, without a custom extension method. – Ryan Jan 07 '20 at 06:25
111

Your helper method is the cleanest way to do it, IMO. If you pass in a list or an array, then an unscrupulous piece of code could cast it and change the contents, leading to odd behaviour in some situations. You could use a read-only collection, but that's likely to involve even more wrapping. I think your solution is as neat as it gets.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • well if the list/array is built ad-hoc, its scope ends after the method call, so it shouldn't cause problems – Mario F Oct 16 '09 at 12:55
  • If sent in as an array, how can it be changed? I guess it could be cast to an array, and then change the reference to something else, but what good would that do? (I'm probably missing something though...) – Svish Oct 16 '09 at 12:55
  • 2
    Suppose you decided to create one enumerable to pass to two different methods... then the first one cast it to an array and changed the contents. You then pass it as an argument to another method, unaware of the change. I'm not saying it's likely, just that having something mutable when it doesn't need to be is less neat than naturla immutability. – Jon Skeet Oct 16 '09 at 12:58
  • 3
    This is an accepted answer, and most likely to be read, so I will add my concern here. I tried this method, but that broke my previously compiling call to `myDict.Keys.AsEnumerable()` where `myDict` was of type `Dictionary>`. After I renamed the extension method to `SingleItemAsEnumerable`, everything started to work. Cannot convert IEnumerable>.KeyCollection>' to 'IEnumerable'. An explicit conversion exists (are you missing a cast?) I can live with a hack for a while, but can other power hackers find a better way? – Hamish Grubijan Oct 17 '11 at 17:24
  • 3
    @HamishGrubijan: It sounds like you wanted just `dictionary.Values` to start with. Basically it's not clear what's going on, but I suggest you start a new question about it. – Jon Skeet Oct 17 '11 at 17:33
  • @JonSkeet I expected something like this to be part of MoreLINQ. Is there anything like this there? Couldnt find. – nawfal Jun 13 '20 at 09:40
  • @nawfal: It's been a long time since I've worked on MoreLINQ I'm afraid. I suggest you have a look in the source code, and file an issue if you can't find it. – Jon Skeet Jun 13 '20 at 09:50
44

In C# 3 (I know you said 2), you can write a generic extension method which might make the syntax a little more acceptable:

static class IEnumerableExtensions
{
    public static IEnumerable<T> ToEnumerable<T>(this T item)
    {
        yield return item;
    }
}

client code is then item.ToEnumerable().

Ðаn
  • 10,934
  • 11
  • 59
  • 95
  • Thanks, I am aware of that (works in .Net 2.0 if I use C# 3.0), I was just wondering if there was a built in mechanism for this. – vgru Oct 16 '09 at 13:04
  • 7
    As a side note, there already exists a `ToEnumerable` extension method for `IObservable`, so this method name also interferes with existing conventions. Honestly, I'd suggest not using an extension method at all, simply because it's *too* generic. – cwharris Nov 25 '13 at 23:07
23

This helper method works for item or many.

public static IEnumerable<T> ToEnumerable<T>(params T[] items)
{
    return items;
}    
Lucius
  • 2,794
  • 4
  • 20
  • 42
duraid
  • 614
  • 7
  • 16
  • 1
    Useful variation, since it supports more than one item. I like that it relies on `params` to build the array, so resulting code is clean-looking. Haven't decided whether I like it more or less than `new T[]{ item1, item2, item3 };` for multiple items. – ToolmakerSteve Oct 14 '15 at 19:12
  • 1
    Smart ! Love it – Mitsuru Furuta May 22 '20 at 12:12
  • Given that it doesn't take a `this` argument so won't be applied to an object, I think `AsEnumerable` is a better name than `ToEnumerable`. – NetMage Jan 12 '22 at 17:18
  • 2
    This actually creates an array in memory: https://sharplab.io/#gist:cf122bcb10a521c314b865dc5c7a6581. **Don't use it if you don't want memory allocation.** – Teejay Mar 07 '23 at 21:55
12

I'm kind of surprised that no one suggested a new overload of the method with an argument of type T to simplify the client API.

public void DoSomething<T>(IEnumerable<T> list)
{
    // Do Something
}

public void DoSomething<T>(T item)
{
    DoSomething(new T[] { item });
}

Now your client code can just do this:

MyItem item = new MyItem();
Obj.DoSomething(item);

or with a list:

List<MyItem> itemList = new List<MyItem>();
Obj.DoSomething(itemList);
Joshua Starner
  • 1,573
  • 1
  • 13
  • 13
  • 21
    Even better, you could have `DoSomething(params T[] items)` which means the compiler would handle the conversion from a single item to an array. (This would also allow you to pass in multiple separate items and, again, the compiler would handle converting them to an array for you.) – LukeH Oct 16 '09 at 13:26
  • I think I like this one more too, it can use new[] { item } without the generic parameter T and keeps the client use syntax cleaner if used many times. – Kioshiki Dec 08 '21 at 19:28
10

This is 30% faster than yield or Enumerable.Repeat when used in foreach due to this C# compiler optimization, and of the same performance in other cases.

public struct SingleSequence<T> : IEnumerable<T> {
    public struct SingleEnumerator : IEnumerator<T> {
        private readonly SingleSequence<T> _parent;
        private bool _couldMove;
        public SingleEnumerator(ref SingleSequence<T> parent) {
            _parent = parent;
            _couldMove = true;
        }
        public T Current => _parent._value;
        object IEnumerator.Current => Current;
        public void Dispose() { }

        public bool MoveNext() {
            if (!_couldMove) return false;
            _couldMove = false;
            return true;
        }
        public void Reset() {
            _couldMove = true;
        }
    }
    private readonly T _value;
    public SingleSequence(T value) {
        _value = value;
    }
    public IEnumerator<T> GetEnumerator() {
        return new SingleEnumerator(ref this);
    }
    IEnumerator IEnumerable.GetEnumerator() {
        return new SingleEnumerator(ref this);
    }
}

in this test:

    // Fastest among seqs, but still 30x times slower than direct sum
    // 49 mops vs 37 mops for yield, or c.30% faster
    [Test]
    public void SingleSequenceStructForEach() {
        var sw = new Stopwatch();
        sw.Start();
        long sum = 0;
        for (var i = 0; i < 100000000; i++) {
            foreach (var single in new SingleSequence<int>(i)) {
                sum += single;
            }
        }
        sw.Stop();
        Console.WriteLine($"Elapsed {sw.ElapsedMilliseconds}");
        Console.WriteLine($"Mops {100000.0 / sw.ElapsedMilliseconds * 1.0}");
    }
Community
  • 1
  • 1
V.B.
  • 6,236
  • 1
  • 33
  • 56
  • Thanks, it makes sense to create a struct for this case to reduce GC burden in tight loops. – vgru Dec 02 '15 at 10:02
  • 3
    Both the enumerator and enumerable are going to get boxed when returned.... – Stephen Drew Apr 03 '17 at 06:45
  • 2
    Don't compare using Stopwatch. Use Benchmark.NET https://github.com/dotnet/BenchmarkDotNet – NN_ Nov 05 '18 at 10:54
  • 5
    Just measured it and `new [] { i }` option is about 3.2 times faster then your option. Also your option is about 1.2 times faster then extension with `yield return`. – lorond May 20 '19 at 15:02
  • You can speed this up by using another C# compiler optimization: add a method `SingleEnumerator GetEnumerator()` that returns your struct. The C# compiler will use this method (it looks it up via duck typing) instead of the interface ones and thus avoids boxing. Many built-in collections utilize this trick, like [List](https://source.dot.net/#System.Private.CoreLib/List.cs,576). Note: this will only work when you have a direct refercne to `SingleSequence`, like in your example. If you store it in an `IEnumerable<>` variable then the trick won't work (the interface method will be used) – enzi Mar 24 '20 at 16:26
  • Your timings take unfair advantage of the C# optimizations for `foreach`: no one is going to realistically call `foreach` on a singleton collection - try going through the `IEnumerable` interface in the `foreach` instead. – NetMage Aug 03 '20 at 22:43
  • @NetMage Would be possible to elaborate a little more on that statement? I would like to learn more about it – Camadas Jan 12 '22 at 13:25
  • @Camadas As discussed in the article pointed to in the answer, the C# compiler has a `foreach` optimization for `IEnumerable` to avoid going through the interface if possible. This answer has a lot of code to take advantage of that `foreach` optimization but the purpose is to create a singleton, so it is unlikely to be used in `foreach` in a way that will be useful. – NetMage Jan 12 '22 at 17:20
9

Either (as has previously been said)

MyMethodThatExpectsAnIEnumerable(new[] { myObject });

or

MyMethodThatExpectsAnIEnumerable(Enumerable.Repeat(myObject, 1));

As a side note, the last version can also be nice if you want an empty list of an anonymous object, e.g.

var x = MyMethodThatExpectsAnIEnumerable(Enumerable.Repeat(new { a = 0, b = "x" }, 0));
erikkallen
  • 33,800
  • 13
  • 85
  • 120
  • Thanks, although Enumerable.Repeat is new in .Net 3.5. It seems to behave similar to the helper method above. – vgru Oct 16 '09 at 13:28
9

I agree with @EarthEngine's comments to the original post, which is that 'AsSingleton' is a better name. See this wikipedia entry. Then it follows from the definition of singleton that if a null value is passed as an argument that 'AsSingleton' should return an IEnumerable with a single null value instead of an empty IEnumerable which would settle the if (item == null) yield break; debate. I think the best solution is to have two methods: 'AsSingleton' and 'AsSingletonOrEmpty'; where, in the event that a null is passed as an argument, 'AsSingleton' will return a single null value and 'AsSingletonOrEmpty' will return an empty IEnumerable. Like this:

public static IEnumerable<T> AsSingletonOrEmpty<T>(this T source)
{
    if (source == null)
    {
        yield break;
    }
    else
    {
        yield return source;
    }
}

public static IEnumerable<T> AsSingleton<T>(this T source)
{
    yield return source;
}

Then, these would, more or less, be analogous to the 'First' and 'FirstOrDefault' extension methods on IEnumerable which just feels right.

Jason Boyd
  • 6,839
  • 4
  • 29
  • 47
  • I like the simplicity and clarity of this solution. Now we have nullable reference types, the first signature could perhaps be `public static IEnumerable AsSingletonOrEmpty(this T? source)` – Giles Jun 29 '22 at 13:08
  • Sorry - I missed the end off my previous comment: `where T : notnull` – Giles Jul 01 '22 at 09:54
8

For those wondering about performance, while @mattica has provided some benchmarking information in a similar question referenced above, My benchmark tests, however, have provided a different result.

In .NET 7, yield return value is ~9% faster than new T[] { value } and allocates 75% the amount of memory. In most cases, this is already hyper-performant and is as good as you'll ever need.

I was curious if a custom single collection implementation would be faster or more lightweight. It turns out because yield return is implemented as IEnumerator<T> and IEnumerable<T>, the only way to beat it in terms of allocation is to do that in my implementation as well.

If you're passing IEnumerable<> to an outside library, I would strongly recommend not doing this unless you're very familiar with what you're building. That being said, I made a very simple (not-reuse-safe) implementation which was able to beat the yield method by 5ns and allocated only half as much as the array.

Because all tests were passed an IEnumerable<T>, value types generally performed worse than reference types. The best implementation I had was actually the simplest - you can look at the SingleCollection class in the gist I linked to. (This was 2ns faster than yield return, but allocated 88% of what the array would, compared to the 75% allocated for yield return.)

TL:DR; if you care about speed, use yield return item. If you really care about speed, use a SingleCollection.

Stroniax
  • 718
  • 5
  • 15
7

Although it's overkill for one method, I believe some people may find the Interactive Extensions useful.

The Interactive Extensions (Ix) from Microsoft includes the following method.

public static IEnumerable<TResult> Return<TResult>(TResult value)
{
    yield return value;
}

Which can be utilized like so:

var result = EnumerableEx.Return(0);

Ix adds new functionality not found in the original Linq extension methods, and is a direct result of creating the Reactive Extensions (Rx).

Think, Linq Extension Methods + Ix = Rx for IEnumerable.

You can find both Rx and Ix on CodePlex.

cwharris
  • 17,835
  • 4
  • 44
  • 64
7

As I have just found, and seen that user LukeH suggested too, a nice simple way of doing this is as follows:

public static void PerformAction(params YourType[] items)
{
    // Forward call to IEnumerable overload
    PerformAction(items.AsEnumerable());
}

public static void PerformAction(IEnumerable<YourType> items)
{
    foreach (YourType item in items)
    {
        // Do stuff
    }
}

This pattern will allow you to call the same functionality in a multitude of ways: a single item; multiple items (comma-separated); an array; a list; an enumeration, etc.

I'm not 100% sure on the efficiency of using the AsEnumerable method though, but it does work a treat.

Update: The AsEnumerable function looks pretty efficient! (reference)

Community
  • 1
  • 1
teppicymon
  • 71
  • 1
  • 2
  • 2
    Actually, you don't need `.AsEnumerable()` at all. Array `YourType[]` already implements `IEnumerable`. But my question was referring to the case when only the second method (in your example) is available, and you are using .NET 2.0, and you want to pass a single item. – vgru Nov 10 '10 at 12:08
  • 3
    Yes, it does, but you'll find you may get a stack overflow ;-) – teppicymon Nov 10 '10 at 15:52
  • And to actually answer your real question (not the one I was actually looking to answer for myself!), yeah you pretty much have to convert it to an array as per Mario's answer – teppicymon Nov 10 '10 at 15:53
  • 2
    How about just defining an `IEnumerable MakeEnumerable(params T[] items) {return items;}` method? One could then use that with anything that expected an `IEnumerable`, for any number of discrete items. The code should be essentially as efficient as defining a special class to return a single item. – supercat Sep 21 '12 at 18:40
5

I recently asked the same thing on another post

Is there a way to call a C# method requiring an IEnumerable<T> with a single value? ...with benchmarking.

I wanted people stopping by here to see the brief benchmark comparison shown at that newer post for 4 of the approaches presented in these answers.

It seems that simply writing new[] { x } in the arguments to the method is the shortest and fastest solution.

Bishan
  • 15,211
  • 52
  • 164
  • 258
mattica
  • 357
  • 3
  • 8
4

This may not be any better but it's kind of cool:

Enumerable.Range(0, 1).Select(i => item);
nawfal
  • 70,104
  • 56
  • 326
  • 368
Ken Lange
  • 65
  • 1
  • 1
  • It's not. It's different. – nawfal Jun 10 '14 at 10:29
  • 3
    Ewww. That's a lot of detail, just to turn an item into an enumerable. – ToolmakerSteve Oct 14 '15 at 19:17
  • 4
    This is the equivalent of using a [Rube Goldberg machine](https://www.youtube.com/watch?v=auIlGqEyTm8) to make breakfast. Yes it works, but it jumps through 10 hoops to get there. A simple thing like this can be the performance bottleneck when done in a tight loop that's executed millions of times. In practice, the performance aspect doesn't matter in 99% of cases, but personally I still think it's gross unnecessary overkill. – enzi Mar 24 '20 at 16:42
4

Sometimes I do this, when I'm feeling impish:

"_".Select(_ => 3.14)  // or whatever; any type is fine

This is the same thing with less shift key presses, heh:

from _ in "_" select 3.14

For a utility function I find this to be the least verbose, or at least more self-documenting than an array, although it'll let multiple values slide; as a plus it can be defined as a local function:

static IEnumerable<T> Enumerate (params T[] v) => v;
// usage:
IEnumerable<double> example = Enumerate(1.234);

Here are all of the other ways I was able to think of (runnable here):

using System;
using System.Collections.Generic;
using System.Linq;

public class Program {
    
    public static IEnumerable<T> ToEnumerable1 <T> (T v) {
        yield return v;
    }
    
    public static T[] ToEnumerable2 <T> (params T[] vs) => vs;
    
    public static void Main () {
        static IEnumerable<T> ToEnumerable3 <T> (params T[] v) => v;
        p( new string[] { "three" } );
        p( new List<string> { "three" } );
        p( ToEnumerable1("three") ); // our utility function (yield return)
        p( ToEnumerable2("three") ); // our utility function (params)
        p( ToEnumerable3("three") ); // our local utility function (params)
        p( Enumerable.Empty<string>().Append("three") );
        p( Enumerable.Empty<string>().DefaultIfEmpty("three") );
        p( Enumerable.Empty<string>().Prepend("three") );
        p( Enumerable.Range(3, 1) ); // only for int
        p( Enumerable.Range(0, 1).Select(_ => "three") );
        p( Enumerable.Repeat("three", 1) );
        p( "_".Select(_ => "three") ); // doesn't have to be "_"; just any one character
        p( "_".Select(_ => 3.3333) );
        p( from _ in "_" select 3.0f );
        p( "a" ); // only for char
        // these weren't available for me to test (might not even be valid):
        //   new Microsoft.Extensions.Primitives.StringValues("three")
        
    }

    static void p <T> (IEnumerable<T> e) =>
        Console.WriteLine(string.Join(' ', e.Select((v, k) => $"[{k}]={v,-8}:{v.GetType()}").DefaultIfEmpty("<empty>")));

}
Jason C
  • 38,729
  • 14
  • 126
  • 182
3

To be filed under "Not necessarily a good solution, but still...a solution" or "Stupid LINQ tricks", you could combine Enumerable.Empty<>() with Enumerable.Append<>()...

IEnumerable<string> singleElementEnumerable = Enumerable.Empty<string>().Append("Hello, World!");

...or Enumerable.Prepend<>()...

IEnumerable<string> singleElementEnumerable = Enumerable.Empty<string>().Prepend("Hello, World!");

The latter two methods are available since .NET Framework 4.7.1 and .NET Core 1.0.

This is a workable solution if one were really intent on using existing methods instead of writing their own, though I'm undecided if this is more or less clear than the Enumerable.Repeat<>() solution. This is definitely longer code (partly due to type parameter inference not being possible for Empty<>()) and creates twice as many enumerator objects, however.

Rounding out this "Did you know these methods exist?" answer, Array.Empty<>() could be substituted for Enumerable.Empty<>(), but it's hard to argue that makes the situation...better.

Lance U. Matthews
  • 15,725
  • 6
  • 48
  • 68
2

The easiest way I'd say would be new T[]{item};; there's no syntax to do this. The closest equivalent that I can think of is the params keyword, but of course that requires you to have access to the method definition and is only usable with arrays.

FacticiusVir
  • 2,037
  • 15
  • 28
2
Enumerable.Range(1,1).Select(_ => {
    //Do some stuff... side effects...
    return item;
});

The above code is useful when using like

var existingOrNewObject = MyData.Where(myCondition)
       .Concat(Enumerable.Range(1,1).Select(_ => {
           //Create my object...
           return item;
       })).Take(1).First();

In the above code snippet there is no empty/null check, and it is guaranteed to have only one object returned without afraid of exceptions. Furthermore, because it is lazy, the closure will not be executed until it is proved there is no existing data fits the criteria.

Earth Engine
  • 10,048
  • 5
  • 48
  • 78
frhack
  • 4,862
  • 2
  • 28
  • 25
  • This answer was automatically tagged "low quality". As explained in the [help](https://stackoverflow.com/help/how-to-answer) ("Brevity is acceptable, but fuller explanations are better."), please edit it to tell the OP what he's doing wrong, what your code is about. – Sandra Rossi Jul 05 '19 at 06:02
  • I see the bulk of this answer, including the part I'm responding to, was edited in later by someone else. but if the intent of the second snippet is to provide a default value if `MyData.Where(myCondition)` is empty, that's already possible (and simpler) with [`DefaultIfEmpty()`](https://docs.microsoft.com/dotnet/api/system.linq.enumerable.defaultifempty): `var existingOrNewObject = MyData.Where(myCondition).DefaultIfEmpty(defaultValue).First();`. That can be further simplified to `var existingOrNewObject = MyData.FirstOrDefault(myCondition);` if you want `default(T)` and not a custom value. – Lance U. Matthews May 20 '20 at 02:01
1

I prefer

public static IEnumerable<T> Collect<T>(this T item, params T[] otherItems)
{
    yield return item;
    foreach (var otherItem in otherItems)
    {
        yield return otherItem;
    }
}

This lets you call item.Collect() if you want the singleton, but it also lets you call item.Collect(item2, item3) if you want

Luke Kubat
  • 371
  • 1
  • 4
0

I'm a bit late to the party but I'll share my way anyway. My problem was that I wanted to bind the ItemSource or a WPF TreeView to a single object. The hierarchy looks like this:

Project > Plot(s) > Room(s)

There was always going to be only one Project but I still wanted to Show the project in the Tree, without having to pass a Collection with only that one object in it like some suggested.
Since you can only pass IEnumerable objects as ItemSource I decided to make my class IEnumerable:

public class ProjectClass : IEnumerable<ProjectClass>
{
    private readonly SingleItemEnumerator<AufmassProjekt> enumerator;

    ... 

    public IEnumerator<ProjectClass > GetEnumerator() => this.enumerator;

    IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
}

And create my own Enumerator accordingly:

public class SingleItemEnumerator : IEnumerator
{
    private bool hasMovedOnce;

    public SingleItemEnumerator(object current)
    {
        this.Current = current;
    }

    public bool MoveNext()
    {
        if (this.hasMovedOnce) return false;
        this.hasMovedOnce = true;
        return true;
    }

    public void Reset()
    { }

    public object Current { get; }
}

public class SingleItemEnumerator<T> : IEnumerator<T>
{
    private bool hasMovedOnce;

    public SingleItemEnumerator(T current)
    {
        this.Current = current;
    }

    public void Dispose() => (this.Current as IDisposable).Dispose();

    public bool MoveNext()
    {
        if (this.hasMovedOnce) return false;
        this.hasMovedOnce = true;
        return true;
    }

    public void Reset()
    { }

    public T Current { get; }

    object IEnumerator.Current => this.Current;
}

This is probably not the "cleanest" solution but it worked for me.

EDIT
To uphold the single responsibility principle as @Groo pointed out I created a new wrapper class:

public class SingleItemWrapper : IEnumerable
{
    private readonly SingleItemEnumerator enumerator;

    public SingleItemWrapper(object item)
    {
        this.enumerator = new SingleItemEnumerator(item);
    }

    public object Item => this.enumerator.Current;

    public IEnumerator GetEnumerator() => this.enumerator;
}

public class SingleItemWrapper<T> : IEnumerable<T>
{
    private readonly SingleItemEnumerator<T> enumerator;

    public SingleItemWrapper(T item)
    {
        this.enumerator = new SingleItemEnumerator<T>(item);
    }

    public T Item => this.enumerator.Current;

    public IEnumerator<T> GetEnumerator() => this.enumerator;

    IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
}

Which I used like this

TreeView.ItemSource = new SingleItemWrapper(itemToWrap);

EDIT 2
I corrected a mistake with the MoveNext() method.

IDarkCoder
  • 709
  • 7
  • 18
  • 1
    The `SingleItemEnumerator` class makes sense, but making a class a "single item `IEnumerable` of itself" seems like a violation of the single responsibility principle. Perhaps it makes passing it around more practical, but I would still prefer to wrap it as needed. – vgru Aug 22 '18 at 11:26