向下倾斜和Linq

时间:2009-03-16 17:42:13

标签: c# linq casting

我有一个名为LabFileBase的基类。我构建了一个List并将我的派生类添加到它。我想根据我定义的键在List中搜索特定对象。我遇到的问题是你如何在LINQ表达式中转发?

以下是一些示例代码:

public abstract class LabFileBase
{
}

public class Sample1 : LabFileBase
{    
    public string ID {get;set;}
    public string Name {get;set;}
    //..
}

public class Sample2 : LabFileBase
{    
    public string ID {get;set;}
    public string Name {get;set;}
    //..
}

我想搜索特定的Sample2类型,但如果我使用这样的常规foreach循环,我需要向下转换:

foreach(var s in processedFiles)  //processedFiles is a List<LabFileBase>
     if (s is Sample2)
         var found = s as Sample2;
             if (found.ID = ID && found.Name == "Thing I'm looking for")
                  //do extra work

我更愿意这样的事情:

var result = processedFiles.Select(s => s.ID == SomeID && s.Name == SomeName);

这是否可行以及涉及什么语法标点符号,或者foreach是我唯一的选项,因为对象不同。 Sample1和Sample2只有ID和Name作为相同的字段。

编辑:感谢所有人的支持和建议,我已经将几乎所有内容都输入了积压工作中。

3 个答案:

答案 0 :(得分:6)

为什么不将IDName放入基类?然后你不需要任何向下转发。

如果 需要进行投射,CastOfType运算符可能会对您有所帮助。每个序列都将序列转换为指定类型的序列:Cast假定每个元素 是正确的类型(如果不是这样,则抛出异常); OfType更像是C#as运算符,只返回恰好类型的元素而忽略其他元素。

答案 1 :(得分:5)

要详细说明Jon的答案,OfType几乎肯定是正确的运算符,如果您不愿意将这些字段放入基类中。例如:

foreach(var s in processedFiles.OfType<Sample2>())
    if(s.ID == ID && s.Name == "Thing I'm looking for")
        // whatever

foreach(var s in processedFiles.OfType<Sample1>())
    if(s.ID == ID && s.Name == "Some other thing")
        // and so on

答案 2 :(得分:0)

有趣的问题。除了Jon Skeet(比这个选项更好),请注意您可以尝试更多的手动替代方案。添加一个附加属性,其中包含对象类型的标识符。

public abstract class LabFileBase
{
    public string LabFileObjectType { get; }
    public string ID {get;set;}
    public string Name {get;set;}
}


public class Sample1 : LabFileBase
{    
    public string LabFileObjectType { get { return "Sample1"; } }
    //..
}

public class Sample2 : LabFileBase
{    
    public string LabFileObjectType { get { return "Sample2"; } }
    //..
}

然后你也可以查询该属性:

var result = processedFiles.Select(s => s.ID == SomeID && s.Name == SomeName && s.LabFileObjectType == "Sample2");