2012-11-29 106 views
2

我有以下非常简单(略)类:名单铸造

// IEntry interface 
public interface IEntry { 
    long Id { get; set; } 
    string Name { get; set; } 
} 

// IEntry implementation 
public class Contact : IEntry { 
    public long Id { get; set; } 
    public string Name { get; set; } 
} 

// DAO Interface 
public interface IEntryDao { 
    List<IEntry> findUnapproved(); 
} 

// abstract base class 
public abstract class AbstractEntryDao : IEntryDao { 
    public virtual List<IEntry> findUnapproved() { 
    List<IEntry> entries = new List<IEntry>(); 
    // ... default load logic 
    return entries; 
    } 
} 

// ContactDao implementation 
public class ContactDao : AbstractEntryDao { 
    public override List<IEntry> findUnapproved() { 
    List<IEntry> contacts = new List<IEntry>(); 
    // ... custom load logic for Contact 
    return contacts; 
    } 
} 

// sample client code 
public void testFindUnapproved() { 
    ContactDao contactDao = new ContactDao(); 
    List<IEntry> contacts = contactDao.findUnapproved(); // <--- this line works (but not what I want) 
    List<Contact> contacts = contactDao.findUnapproved(); // <--- this does not work (which makes sense) 
    List<Contact> contacts = contactDao.findUnapproved() as List<Contact>; // <--- this does not work 

    // here is how i compensate for this problem... but i do not like this 
    List<Contact> list = new List<Contact>(); 
    foreach (IManageableEntry contact in contacts) { 
     list.Add(contact as Contact); 
    } 
} 

我想是一个很短手的方式(或可能使用泛型的DAO接口和抽象类)

List<Contact> contacts = contactDao.findUnapproved(); // <--- can I achieve this using generics in .NET 3.5? 

否则,除了我的示例客户端代码的最后,我认为这是一个糟糕的做法,干净的替代解决方案是什么?

回答

4
List<Contact> contacts = contactDao.findUnapproved().Cast<Contact>().ToList(); 

只记得使用上述文件LINQ命名空间添加

+0

当我用这行代替我的代码时,出现以下错误:无法隐式地将类型'System.Collections.Generic.IEnumerable '转换为'System.Collections.Generic.List ”。存在明确的转换(您是否缺少演员?)。我需要重铸最终的集合吗? –

+1

不,它必须工作,似乎你需要添加另一个.Tolist()方法链后.Cast (),所以它必须是铸().ToList() –

+1

实际上有新的概念在.NET中引入4这使得与泛型很多的工作更加容易,它可能如果你读它是有帮助的http://www.codeproject.com/Articles/72467/C-4-0-Covariance-And-Contravariance-In-Generics HTTP:/ /msdn.microsoft.com/library/dd799517(VS.100).aspx –

2

考虑使用Enumerable.OfType Method,如果findUnapproved可以返回IEntry不同的实现,你只想从列表中得到Contact

List<Contact> contacts = contactDao.findUnapproved().OfType<Contact>().ToList(); 

至于OfType(和Cast)返回IEnumerable<T>你需要调用ToList得到你想要的东西。

+0

是的,我是在最后缺少.ToList()那里。谢谢! –