14

There must be a good standard way of doing this, however every project I work on I have to write my own unity method, or create an inline array etc.

(I hope this will quickly get closed as a duplicate of a question with some great answers on this)

Ian Ringrose
  • 51,220
  • 55
  • 213
  • 317
  • http://stackoverflow.com/questions/4779442/return-single-instance-object-as-ienumerable – Jamie Dixon Jun 21 '11 at 09:47
  • There is an extension method described here that yield returns the value: http://stackoverflow.com/questions/1577822/passing-a-single-item-as-ienumerablet – BoltClock Jun 21 '11 at 09:48

4 Answers4

20

One simple way:

var singleElementSequence = Enumerable.Repeat(value, 1);

Or you could write your own extension method on an unconstrained generic type (usually a bad idea, admittedly... use with care):

public static IEnumerable<T> ToSingleElementSequence<T>(this T item)
{
    yield return item;
}

Use as:

IEnumerable<String> sequence = "foo".ToSingleElementSequence();

I think I'd use Enumerable.Repeat in preference though :)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 3
    I have a 'literate programming' problem with 'abusing' Repeat for this: It says quite the contrary of what the code is trying to achieve: it tries _not_ to repeat any items :) – sehe Jun 21 '11 at 09:51
  • Pitty there is not a Enumerable.FromItem(T item) method... – Ian Ringrose Jun 21 '11 at 09:52
  • 1
    I don't think I like the idea of using `yield` for this. It causes the compiler to generate a completely new enumerator implementation and associated state machine for something that will only ever have one element. Just doing `return new[] { item };` will not do any more allocations and avoid all the heavy code generation. – Sven Jun 21 '11 at 10:10
  • 3
    @Sven: On the other hand, it generates something which is mutable. How much are you happy to rely on people *not* casting it back to an array and potentially mutating it? – Jon Skeet Jun 21 '11 at 10:40
  • 1
    You could compromise and implement `IEnumerable` explicitly, thus avoiding both the state machine and the easily-accessible underlying array. I really don't see much benefit to doing so under normal circumstances, though if I was writing this function for a widely used framework I might consider such a compromise for a potential tiny efficiency boost. – Brian Jun 21 '11 at 13:33
  • 1
    "*extension method on an unconstrained generic type (usually a bad idea, admittedly... use with care)*" - bad because it's attached to *anything* and is over-exposed, so to speak, or is there another, more specific nefariousness here? – ruffin Jun 21 '17 at 15:36
  • 1
    @ruffin: The former. – Jon Skeet Jun 21 '17 at 15:46
  • I would use "AsEnumerable" instead of "ToSingleElementSequence". It is completely enough for people who know what "Enumerable" is. – Victor Yarema Feb 11 '20 at 09:40
  • 1
    @VictorYarema: That clashes with the existing `AsEnumerable` method though. For example, `"foo".AsEnumerable()` would be ambiguous between `Enumerable.AsEnumerable("foo")` and `MyCode.AsEnumerable("foo")`. – Jon Skeet Feb 11 '20 at 09:54
  • @JonSkeet, thanks for correcting me. Yes, there is https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.asenumerable?view=netstandard-2.1 . Just one more observation from my side: having method in core library that converts an object of one type to SAME type is pretty good example of how incompetent people design libraries. – Victor Yarema Feb 11 '20 at 10:06
  • @VictorYarema: I think we'll have to agree to disagree about the competence of the LINQ designers. – Jon Skeet Feb 11 '20 at 10:17
11

the shortest way is

new T[]{value}
alx
  • 257
  • 1
  • 2
5

Edit Just thought of mentioning some of my favourite devices in LINQ:

 internal static IEnumerable<T> Concat<T>(params T[] objs)
 {
      return objs;
 }

 internal static IEnumerable<T> Concat<T>(this IEnumerable<T> e, params T[] objs)
 {
      return e.Concat(objs);
 }

 internal static IEnumerable<T> Concat<T>(this IEnumerable<T> e, params IEnumerable<T>[] seqs)
 {
      foreach (T t in e) yield return t;
      foreach (var seq in seqs)
           foreach (T t in seq) yield return t;
 }

 // this allows you to
 var e1 = Concat(1,2,3);       // 1,2,3
 var e2 = e1.Concat(4,5,6);    // 1,2,3,4,5,6,
 var e3 = e2.Concat(e2, e1, Concat(42)); // 1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,42

Very convenient to define literal lists in any way, shape or form

Another simple way:

 IEnumerable<int> = new [] {42};

Yet another simple way:

 internal static IEnumerable<T> Enumerable<T>(this T obj)
 {
      yield return obj;
 }

 //
 var enumerable = 42.Enumerable();
sehe
  • 374,641
  • 47
  • 450
  • 633
4

You can define your own extension method:

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

There is nothing in the .NET framework that performs this task.

ColinE
  • 68,894
  • 15
  • 164
  • 232