将泛型集合转换为C#2.0中的具体实现

时间:2009-11-10 17:52:58

标签: c# c#-2.0 collections generics casting

选择解决方案

感谢大家的帮助。我决定做以下事情。

public static class PersonCollection
{
    public static List<string> GetNames(RecordCollection<Person> list)
    {
        List<string> nameList = new List<string>(list.Count);

        foreach (Person p in list)
        {
            nameList.Add(p.Name);
        }

        return nameList;
    }
}



我正在尝试将一个通用集合RecordCollection转换为派生集合PersonCollection,但是我得到一个强制转换异常:

RecordCollection<Person> col = this.GetRecords<Person>(this.cbPeople);
PersonCollection people = (PersonCollection)col;

我试图这样做的原因有两个:

  1. 派生类(例如,PersonCollection)可以有实例方法(例如,GetLastNames),它们不应该在基类中。
  2. 方法GetRecords是通用的,因此我可以获得任何Record对象的集合。
  3. 在C# 2.0 中解决此问题的最佳方法是什么?解决这个问题最强烈的优雅方法是什么?

    这是GetRecords的签名:

    public RecordCollection<T> GetRecords<T>(ComboBox cb) where T : Record, new()
    

    这是我的基础实施:

    public abstract class Record : IComparable
    {
        public abstract int CompareTo(object other);
    }
    
    public class RecordCollection<T> : ICollection<T> where T : Record, new()
    {
        private readonly List<T> list;
    
        public RecordCollection()
        {
            this.list = new List<T>();
        }
    
        // Remaining ICollection interface here
    }
    

    我基于该基本实现派生了对象,如下所示:

    public class Person : Record
    {
        public Person()
        {
            // This is intentionally empty
        }
    
        public string Name
        {
            get;
            set;
        }
    
        public override int CompareTo(object other)
        {
            Person real = other as Person;
            return this.Name.CompareTo(real.Name);
        }
    }
    
    public class PersonCollection : RecordCollection<Person>
    {
    
    }
    

3 个答案:

答案 0 :(得分:5)

您的方法不起作用,因为强制转换不会将一个类的实例转换为另一个类的实例。

您没有提供GetRecords&lt;&gt;的代码方法,但可能是GetRecords返回RecordCollection,而不是PersonCollection(它在代码中的某处有新的RecordCollection,不是吗?)。

除非此特定实例实际上是PersonCollection,否则无法将RecordCollection转换为PersonCollection。主要是因为它没有这些额外的方法。

这就像

SomeClass obj=new SomeClass();
DerivedClass o=(DerivedClass)obj; //throws exception

答案 1 :(得分:2)

您最好的选择是在GetRecords内使用某种工厂调用,这样当您请求Person的'集合'时,它将PersonCollection作为RecordCollection<Person>返回

一个天真的实现可以使用一些if,否则你可以通过Dictionary<Type,Type>将具体的集合类型与记录类型相关联。

答案 2 :(得分:1)

一个选项:

在派生类型上创建非扩展静态方法的方法,这些方法接受专门的RecordsCollection,即

public static List<string>GetLastNames( RecordsCollection<Person> people ) 

所以你可以按照

的用法使用
RecordCollection<Person> somePeople = GetRecords<Person>(cbPeople);
List<string> lastNames = PersonCollecion.GetLastNames( somePeople );

它不像扩展方法那么漂亮,但也不是太糟糕。
修改:删除之前发布的错误信息并替换为潜在解决方案