我有一个名为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作为相同的字段。
编辑:感谢所有人的支持和建议,我已经将几乎所有内容都输入了积压工作中。
答案 0 :(得分:6)
为什么不将ID
和Name
放入基类?然后你不需要任何向下转发。
如果 需要进行投射,Cast
和OfType
运算符可能会对您有所帮助。每个序列都将序列转换为指定类型的序列: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");