2017-02-22 52 views
1

我已经创建了一个接口,它具有两个派生类,如下面的代码片段所示,我想访问Linq查询中那些派生类的成员,但我无法这样做。从Linq查询中的接口访问派生类的属性?

模型类结构:

List<IDirDetails> data = LoadData();     
int totalRecords = data.Count; 

if (!string.IsNullOrEmpty(search) && !string.IsNullOrWhiteSpace(search)) 
{ 
    // Apply search 
    data = data.Where(p => p.FileName.ToString().ToLower().Contains(search.ToLower()) || //not allowing to access FileName 
          p.FileSize.ToLower().Contains(search.ToLower()) ||    //not allowing to access FileSize 
          p.FileModified.ToString().ToLower().Contains(search.ToLower())).ToList(); //not allowing to accessFileModified 
} 
下面

是我如何LoadData()

public List<IDirDetails> LoadData() 
{ 
    string userName = HttpContext.User.Identity.Name; 
    var user = _context.Users.FirstOrDefault(m => m.UserName == userName);   
    string[] appList = null; 
    var allDirDetails = new List<IDirDetails>(); //obj of an Interface 
    var allAppExist = _context.UserApplications.Any(ua => ua.AppId == 17 && ua.UserId == user.Id); 

    appList = (from a in _context.Applications 
       join ua in _context.UserApplications on a.Id equals ua.AppId 
       where ua.UserId == user.Id 
       select a.AppName).ToArray(); 

    DirectoryDetails dirDetails = new DirectoryDetails(); 
    dirDetails.ApplicationList = appList; 

    List<DirectoryItemInfo> dirItems = new List<DirectoryItemInfo>(); 
    dirDetails.Items = dirItems; 

    allDirDetails.Add(dirDetails); // adding values into DirectoryDetails 

    string requestPath = Request.Path.Value; 

    string[] requestPathParts = requestPath.Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries); 
    dirDetails.PathElements = requestPathParts; 

    var aapId = _context.Applications.FirstOrDefault(a => a.AppName == requestPathParts[0].ToString()); 

    string[] physicalPaths = (from ap in _context.ApplicationPathElements 
           join a in _context.Applications on ap.AppId equals a.Id 
           where a.Id == aapId.Id 
           select ap.AppPathElement).ToArray(); 
    if (physicalPaths != null && physicalPaths.Length > 0) 
    { 
     foreach (string indexPath in physicalPaths) 
     { 
      DirectoryItemInfo details = GetDirectoryInfo(indexPath, indexPath + "/", DateTime.MinValue);   
      allDirDetails.Add(details); // adding values into DirectoryItemInfo 
     } 
    }    
    return allDirDetails; 
} 
设定值这些类:其中我试图访问这些成员

public interface IDirDetails 
{ 
} 
public class DirectoryDetails: IDirDetails 
{ 
    public string[] PathElements { get; set; } 
    public string[] ApplicationList { get; set; } 

    public List<DirectoryItemInfo> Items { get; set; } 
} 
public class DirectoryItemInfo: IDirDetails 
{ 
    public string FileName { get; set; } 
    public string FileType { get; set; } 
    public string FileSize { get; set; } 
    public string FileIcon { get; set; } 
    public DateTime FileModified { get; set; } 
    public string FilePath { get; set; } 
} 

代码形式

有人可以请建议我应该如何访问所需的衍生成员一个接口的ved类?对您的问题

回答

1

简单的答案是:只投它

data = data.Cast<DirectoryItemInfo>().Where(p => p.FileName.ToString().ToLower().Contains(search.ToLower()) || 
         p.FileSize.ToLower().Contains(search.ToLower()) ||    
         p.FileModified.ToString().ToLower().Contains(search.ToLower())).ToList(); 

或使用OfType

data = data.OfType<DirectoryItemInfo>().Where(p => p.FileName.ToString().ToLower().Contains(search.ToLower()) || 
         p.FileSize.ToLower().Contains(search.ToLower()) ||    
         p.FileModified.ToString().ToLower().Contains(search.ToLower())).ToList(); 

正确答案是:有些事情不对您的模型。要么你不需要接口列表,而是需要特定类型的列表,或者你应该将这些属性移动到接口。

例如,您的LoadData方法返回接口列表,但在您的示例中,您将其用作特定类的列表。你可以改变它:

public List<T> LoadData<T>() where T:IDirDetails 
{ 
    // return specific List 
} 

之后,你可以把它作为:

List<DirectoryItemInfo> data = LoadData<DirectoryItemInfo>(); 

,你并不需要强制转换。在LoadData的某处,你应该决定你将返回哪些元素。

+0

谢谢你的回答,先生,可以请你提出正确的方式实现这些? –

+0

@RahulNagrale我不'不要看到你的整个代码,我在答案中提出了一个建议,但这取决于你在做什么。 –

+0

当我从LoadData()返回'List '时出现错误,错误:'CS0029 \t无法隐式地将类型'System.Collections.Generic.List 转换为'System .Collections.Generic.List ' –

0

您可以使用'OfType'方法从'数据'列表中选择'DirectoryItemInfo'类型的所有项目,并将'Where'的结果转换为'IDirDetails'列表。

data = data.OfType<DirectoryItemInfo>() 
      .Where(p => 
        p.FileName.ToString().ToLower().Contains(search.ToLower()) || 
        p.FileSize.ToLower().Contains(search.ToLower()) || 
        p.FileModified.ToString().ToLower().Contains(search.ToLower())) 
      .ToList<IDirDetails>(); 
0

您只能访问由您的界面定义的那些成员。如果你需要访问该接口的具体实现的成员,你将需要一个具体实现的实例(在你的情况下,一个DirectoryDetailDirectoryItemInfo的实例。

你可以做一些事情与铸造为其他成员说,但你还是访问在一些这样或那样的具体实现的实例。

0

使用OfType过滤型

List<IDirDetails> data = LoadData();     
int totalRecords = data.Count; 

if (!string.IsNullOrEmpty(search) && !string.IsNullOrWhiteSpace(search)) 
{ 
    // Apply search 
    data = data.OfType<DirectoryItemInfo>().Where(p => p.FileName.ToString().ToLower().Contains(search.ToLower()) || 
          p.FileSize.ToLower().Contains(search.ToLower()) ||    
          p.FileModified.ToString().ToLower().Contains(search.ToLower())).Cast<IDirDetails>().ToList(); 
} 
+0

如果列表中有'DirectoryDe​​tails','Cast'将不起作用。 – xwlantian

相关问题