c#过滤lambda中的动态属性名称

时间:2013-03-08 21:40:03

标签: c# asp.net linq lambda

我在命名不佳的房产方面遇到了麻烦:

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; }
}

这应该是List<string>类型的一个属性。但其他人想出了这个想法,我现在无法改变结构。

我有一个返回大量Word个对象的方法。我想要做的是过滤掉一个或多个Word属性中具有匹配字符串的每个AltXX实例。

这是我到目前为止所做的:

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

如果我将它扩展一下,这将作为我的过滤器。但我的问题是:这是否可以使用lambda表达式解决?

3 个答案:

答案 0 :(得分:7)

所以我们将从一个简单的帮助(可能是扩展)方法开始,因为我们有一堆属性而不是列表:

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;
}

如果它可以有N个属性而不是五个属性,你可以重构它以使用反射。如果你真的如此,上帝会帮助你。把你放在那个位置的开发人员,而不是仅仅为我使用List一次。

有了这个,它还不错:

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

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

我希望该单词的替代词Where Any包含搜索文字。它读起来就像是有效的。

答案 1 :(得分:1)

您可以通过创建帮助程序类,以向后兼容的方式将类转换为List<string>

E.G。

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};
    }
}

答案 2 :(得分:0)

你可以做的最好的事情是在你的应用程序开始时使用反射来构建表达式树,编译成lambdas,然后保存那些lambda以便重复使用。

反思速度缓慢的代价只支付一次,然后它就像你从头开始编译它一样快。

然而,写这些表达树是一种痛苦,所以如果你不关心性能(它很慢,但速度不慢),那么你的反思应该没问题。