代码之家  ›  专栏  ›  技术社区  ›  Armbrat

在C 2.0中将通用集合强制转换为具体实现

  •  1
  • Armbrat  · 技术社区  · 16 年前

    选择溶液

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

    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方法是通用的,因此我可以获取任何记录对象的集合。

    用C语言解决这个问题的最佳方法是什么?# ?最重要的是什么 优雅的方法 解决这个问题?

    这是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 回复  |  直到 16 年前
        1
  •  5
  •   yu_sha    16 年前

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

    您没有给出getrecords<gt;方法的代码,但可能getrecords返回recordcollection,而不是person collection(它在代码中的某个位置有新的recordcollection,不是吗?).

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

    这就像

    SomeClass obj=new SomeClass();
    DerivedClass o=(DerivedClass)obj; //throws exception
    
        2
  •  2
  •   leppie    16 年前

    你最好的办法是在里面打个工厂电话。 GetRecords ,以便当您请求 Person 它会回来的 PersonCollection 作为 RecordCollection<Person> .

    一个简单的实现可以使用一些if,否则您可以通过 Dictionary<Type,Type> .

        3
  •  1
  •   µBio    16 年前

    一种选择:

    使派生类型上的方法成为采用专用记录集合的非扩展静态方法,即

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

    所以你可以使用

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

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