1

I'm having trouble with poorly named properties:

public class Word
{
     public string Alt01 { get;set; }
     public string Alt02 { get;set; }
     public string Alt03 { get;set; }
     public string Alt04 { get;set; }
     public string Alt05 { get;set; }
}

This should probably have been one property of the type List<string>. But someone else came up with this idea, and I can't change the structure at the moment.

I have a method that returns a lot of Word objects. What I would like to do is to filter out each Word instance that has a matching string in one or more of the AltXX properties.

This is what I have so far:

foreach(var word in resultList) //<-- List<Word> 
{
    var alt01 = word.GetType().GetProperty("alt01").GetValue(word, null);
}

This would work as my filter if I extend it a bit. But my question is: Is this solvable using lambda expressions?

4

3 に答える 3

7

So we'll start with a simple helper (possibly extension) method since we have a bunch of properties and not a list:

public static IEnumerable<string> getAlts(Word word)
{
    yield return word.Alt01;
    yield return word.Alt02;
    yield return word.Alt03;
    yield return word.Alt04;
    yield return word.Alt05;
}

You could refactor that to use reflection if it could have N properties instead of exactly five. God help you if that's really the case for you. Slap the developer who put you in that position instead of just using a List once for me too.

With that, it's not too bad:

List<Word> words = new List<Word>();

string searchText = "foo";
var query = words.Where(word => getAlts(word).Any(alt => alt.Contains(searchText)));

I want the words Where Any of the alt's for that word contain the search text. It reads just like it works.

于 2013-03-08T21:46:22.280 に答える
1

List<string>ヘルパークラスを作成することにより、下位互換性のある方法でクラスを変換できます。

例えば

class QueryFriendlyWordList
{
    public List<string> Words;

    public QueryFriendlyWordList(Word words)
    {
            Words = new List<string> {words.P1,words.P2, words.P3, words.P4};
    }
}

使用法

        Word words = new Word {P1 = "abcd", P2 = "abc", P3 = "def", P4 = "qwre"};
        var queryable = new QueryFriendlyWordList(words);
        var result = queryable.Words.Where(w => w.Contains("a"));

静的はさらに簡単です:

static class WordConverter
{       
    public static List<string> Convert(Word words)
    {
            return new List<string> {words.P1,words.P2, words.P3, words.P4};
    }
}
于 2013-03-08T21:53:43.933 に答える
0

Best you can do is use reflection one time at the start of your app to build expression trees, which compile into lambdas, then save those lambdas to be re-used.

The price for the slowness of reflection is only paid once, then afterward it's as fast as if you had compiled it from the beginning.

However, it's a pain in the neck to write those expression trees, so if you're not concerned about performance (it's slow, but not THAT slow), then your reflection should be fine.

于 2013-03-08T21:45:28.900 に答える