David Smit David Smit - 27 days ago 7
C# Question

LINQ select to new object, setting values of object in function

I am using

LINQ
to select a new
twoWords
object into a
List
of this objects, and set the values by calling a function/method.

Please see if this makes sense, I have simplified it a lot. I really want to use the linq statements
from
select
.

The first function in
GOGO
will work, the second one fails (they do not perform the same task though)

// simple class containing two strings, and a function to set the values
public class twoWords
{
public string word1 { get; set; }
public string word2 { get; set; }

public void setvalues(string words)
{
word1 = words.Substring(0,4);
word2 = words.Substring(5,4);
}


}

public class GOGO
{

public void ofCourseThisWillWorks()
{
//this is just to show that the setvalues function is working
twoWords twoWords = new twoWords();
twoWords.setvalues("word1 word2");
//tada. object twoWords is populated
}

public void thisdoesntwork()
{
//set up the test data to work with
List<string> stringlist = new List<string>();
stringlist.Add("word1 word2");
stringlist.Add("word3 word4");
//end setting up

//we want a list of class twoWords, contain two strings :
//word1 and word2. but i do not know how to call the setvalues function.
List<twoWords> twoWords = (from words in stringlist
select new twoWords().setvalues(words)).ToList();
}
}


The second function of
GOGO
will cause an error :


The type of the expression in the select clause is incorrect. Type inference failed in the call to 'Select'.


My question is, how do I select the new
twoWords
object in the above
from
clause, while setting the values using the
setvalues
function?

Regards
3kwartappel

Answer

You need to use a statement lambda, which means not using a query expression. In this case I wouldn't use a query expression anyway, given that you've only got a select...

List<twoWords> twoWords = stringlist.Select(words => {
                                                var ret = new twoWords();
                                                ret.setvalues(words);
                                                return ret;
                                            })
                                    .ToList();

Or alternatively, just have a method which returns an appropriate twoWords:

private static twoWords CreateTwoWords(string words)
{
    var ret = new twoWords();
    ret.setvalues(words);
    return ret;
}

List<twoWords> twoWords = stringlist.Select(CreateTwoWords)
                                    .ToList();

This would also let you use a query expression if you really wanted to:

List<twoWords> twoWords = (from words in stringlist 
                           select CreateTwoWords(words)).ToList();

Of course another option would be to give twoWords a constructor which did the right thing to start with, at which point you wouldn't just need to call a method...