1

I have the following code:

        foreach (var b in userNames.Select(a => new User()))
        {
          ...
        }

This works quite well, since it gives me all "fresh" user objects, however Code Analysis complains that I shouldn't create unused locals, so my question is, is there a way of ignoring the arguments (similar to the "_" in Haskell).

PS: prehaps my example is not the best. I am sorry for this.

Thanks!

Update 1

I got the following code analysis error: [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "a"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "b")]

Snowflake
  • 2,869
  • 3
  • 22
  • 44
  • 4
    The question is why would you want to do this in the first place? – Santhos Feb 03 '15 at 10:07
  • 2
    Why would you want to do this? You project each element of `userNames` to a `new User()` object. Then you iterate trough this sequence, of these objects. Why you need to do this? – Christos Feb 03 '15 at 10:09
  • 1
    Your example may not be the best one, but I can imagine that it is sometimes necessary to ignore the argument. Not a big deal IMHO. – Dennis_E Feb 03 '15 at 10:11

5 Answers5

2

_ is a perfectly valid variable name in C#. So writing

foreach(var b in userNames.Select(_ => new User()))
{
}

is perfectly valid code. It depends on your analysis rules whether it accepts such cases or not.

However, your code is indeed quite suspicious: you're mapping a collection of user names to a collection of users but you're not specifying a direct relation between the two: maybe you wanted to write something like this:

foreach(var b in userNames.Select(username => new User(username)))
RePierre
  • 9,358
  • 2
  • 20
  • 37
1

If quantity is your concern, and need linq, rewrite it as

foreach(var user in Enumerable.Repeat(()=>new User(),Usernames.Count).Select(x=>x()))
{

}

But, it may look ugly based on how you see it.

Mat J
  • 5,422
  • 6
  • 40
  • 56
1

To create a collection of objects of a given size, just use the length from the original collection.

var newColletion = Enumerable.Repeat(false, input.Length)
                             .Select(_ => new User());

but perhaps better would be your own helper method

static class MyEnumerable {
  IEnumerable<T> Repeat<T>(Func<T> generator, int count) {
    for (var i = 0; i < count; ++i) {
      yield return generator();
    }
  }
}

and then use

var newCollection = MyEnumerable.Repeat(() => new User(), oldCollection.Length);
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Richard
  • 106,783
  • 21
  • 203
  • 265
  • 1
    That's quite a scratching of the left ear with the toe of your right foot! It hides whatever intention the initial code was supposed to suggest. – RePierre Feb 03 '15 at 10:20
0

Select performs a projection on the collection on which it is called, performing a specified operation on each element and returning the transformed results in another collection. If you do not need to perform any operation on the lambda element, you'd better simply create an array of User objects directly.

Answering your edit, as I said above, you can simply do this:

var NewColl = new User[userNames.Length];

As for initialization, you could have done this:

Enumerable.Repeat<User>(new User(), userNames.Length);
dotNET
  • 33,414
  • 24
  • 162
  • 251
  • 1
    How would you directly create an array of initialised `User` objects with the same length as the `userNames` enumeration? – Rawling Feb 03 '15 at 10:11
  • 2
    @dotNET, that does not create an array of initialized `User` objects - that creates an array of nulls. – RePierre Feb 03 '15 at 10:13
  • @dotNET That creates a set of the same object repeated multiple times, as already noted in the comments on CodeCaster's answer. – JLRishe Feb 03 '15 at 10:17
0

I'm sure there is a valid case where you would want to ignore arguments like this, but this doesn't seem like one of them. If you are creating N User objects for N userNames, surely you want to couple those together?

foreach (var b in userNames.Select(a => new { name = a, user = new User() }))
{
    ...
}

Then you won't have any unused arguments.

But the question remains why you aren't just doing this:

foreach (var name in userNames)
{
    var user = new User();
    // ...
}

As far as I can see, your use of .Select() makes no sense here.

JLRishe
  • 99,490
  • 19
  • 131
  • 169