1

Is "materialize" a good name for a code like this, or is there a better (and official) one?

enumerable as ICollection<T> ?? enumerable .ToArray()

EDIT: I clarified the code (and its purposes)

// or "MaterializeIfNecessary"
public static IEnumerable<T> Materialize<T>(this IEnumerable<T> source)
{
    // if you use code analysis tools like resharper, you may have to return a 
    // different type to turn off warnings - even a placeholder interface like 
    // IMaterializedEnumerable<T> : IEnumerable<T> { } 

    if (source == null) return null;

    return source as ICollection<T> ?? source.ToArray();
}

The problem:

static void Save(IEnumerable<string> strings)
{
    // The following code is Resharper suggested solution to 
    // "Possible multiple enumeration of IEnumerable" warning
    // ( http://confluence.jetbrains.com/display/ReSharper/Possible+multiple+enumeration+of+IEnumerable ):
    strings = strings as string[] ?? strings.ToArray(); // you're not calling 
                                                        // ToArray because you 
                                                        // need an array, here

    if (strings.Any(s => s.Length >= 255)) throw new ArgumentException();

    File.AppendAllLines("my.path.txt", strings);
}

With the extension method, the first line should become more declarative:

strings = strings.MaterializeIfNecessary();
Tony
  • 818
  • 1
  • 7
  • 21
Notoriousxl
  • 1,540
  • 1
  • 16
  • 27
  • 3
    I'd call it `AsReadOnly` or `ToReadOnlyCollection` – Magnus Feb 11 '13 at 20:16
  • 1
    @Magnus that should be an answer :) BTW I think `AsReadOnlyCollection` describes result better – Sergey Berezovskiy Feb 11 '13 at 20:19
  • Why would you cast IEnumerable to IReadOnlyCollection? http://stackoverflow.com/a/55661/211627 – JDB Feb 11 '13 at 20:20
  • 1
    @lazyberezovsky I'll do that. – Magnus Feb 11 '13 at 20:23
  • It's only purpose is: 1) call deferred execution immediately 2) and/or prevent multiple enumerations (in those points/algorithms you need it) The return type should be also "IEnumerable", I use IReadOnlyCollection only to let code analysis tools (like resharper) understand that the method returns a "static" copy of source (as ToArray()/ToList() do). Try/casts are to prevent useless "materialization" of already "materialized" sources. I was in a hurry, I'll edit the post with more clear info as soon as I can – Notoriousxl Feb 11 '13 at 20:47
  • @Magnus: I agree that the name should have the "IfNecessary" subfix (or something like that). I used to name it "PreventMultipleEnumerations", but its purpose could also be to "flush" the deferred execution, so I decided to rename it, searching for an official term. Because of its purpose, if source is already "materialized", is useless (and unefficient) to ToList()/ToArray() it againg – Notoriousxl Feb 11 '13 at 21:19
  • I've edited the question, I'm sorry if it wasn't clear from the beginning. I was looking for the name of this: enumerable as ICollection ?? enumerable .ToArray() – Notoriousxl Feb 11 '13 at 21:44
  • @Notoriousxl I think you should rather change your save method ta take in `IList` instead. – Magnus Feb 11 '13 at 23:28
  • 1
    I dont think the answerers got what you were trying to ask. What you're trying to do is exactly "materializing" the `IEnumerable` as a solid collection type since it can also be merely a query. And you have done it quite good (I mean the method implementation). But there is a catch here: your method returns either the existing collection (by a mere cast) or a new collection. For the first operation a verb like `Materialize` is good as a function name since you're acting on the list, but for the second operation, something like `To...` is more consistent with framework defined functions. – nawfal Sep 28 '13 at 14:16
  • 1
    But that doesn't go well with its first operation. Anyway adding "IfNecessary" is not required, in fact I would suggest against it. May be a better naming is `AsCollection` or even just `Materialize` is not bad. Another suggestion is to return `ICollection` since you're executing the call and mostly something more fleshed out than an `IEnumerable` makes sense there. See a related link here: http://stackoverflow.com/questions/4621561/is-there-a-way-to-memorize-or-materialize-an-ienumerable – nawfal Sep 28 '13 at 14:22
  • 1
    @nawfal that's exactly what I did, since I found that the term is used in official MSDN articles too. :) But I didn't return ICollection, since it exposes "write" methods. – Notoriousxl Sep 28 '13 at 21:52

2 Answers2

1

I'd call it ToReadOnlyCollection. It gives more information about what the function is actually doing.
As for materializing the source it seems to do so only if ToArray() is called. (Wrapping the source only would not materialize it)

Magnus
  • 45,362
  • 8
  • 80
  • 118
  • 1
    IEnumerable is already read only, so I still think `AsReadOnlyCollection` is a little better name :) – Sergey Berezovskiy Feb 11 '13 at 20:24
  • @lazyberezovsky Yes, that name would also work. Especially if the function only wrapped the source `IEnumerable`. But it seems it sometimes calls `ToArray` before the wrapping that's why `To` might be a better naming. – Magnus Feb 11 '13 at 20:30
  • `ToXY` is best, because as a extension method it can be used like `ToList()` or `ToArray()`. But I do not understand why one needs that. – Mare Infinitus Feb 11 '13 at 20:33
  • Yep, I already looked on framework methods like `AsEnumerable` and also think that `AsXXX` not good here) – Sergey Berezovskiy Feb 11 '13 at 20:33
  • http://stackoverflow.com/questions/14819990/enumerable-is-materialize-an-official-term/14820288#comment20761949_14819990 – Notoriousxl Feb 11 '13 at 20:48
1

As @Magnus already suggested, ToReadOnlyCollection is a good descriptive name for your method. Also I think AsReadOnlyCollection is not that good name. Usually AsXXX methods do not covert or wrap source. Such methods simply return source as one of interfaces already implemented by source. You can use such method instead of casting.

And Materialize tells totally nothing about intent of method. What does it mean? I will be able to touch my sequence with hands? It will be printed on paper? Saved to file?

And yes, I also don't understand why you need to convert IEnumerable which is already read only to ReadOnlyCollection.

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
  • The underlying collection that the source `IEnumerable` points to might not be readonly, you may be able to cast it to a normal list and add stuff to it. If the collection _is_ a readonly collection that is not possible. – Magnus Feb 11 '13 at 20:34
  • http://stackoverflow.com/questions/14819990/enumerable-is-materialize-an-official-term/14820288#comment20761949_14819990 – Notoriousxl Feb 11 '13 at 20:49