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

发布于 2024-08-10 05:46:32 字数 1876 浏览 6 评论 0原文

选择的解决方案

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

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 对象的集合。

在 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>
{

}

Chosen Solution

Thanks for the help everyone. I've decided to do the following.

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;
    }
}


I'm trying to cast a generic collection RecordCollection to a derived collection PersonCollection, but I get a cast exception:

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

The reason I'm trying to do this is two-fold:

  1. The derived classes (eg, PersonCollection) can have instance methods (eg, GetLastNames) which shouldn't be in the base class.
  2. The method GetRecords is generic so I can get a collection of any Record objects.

What is the best approach to solve this in C# 2.0? What is the most elegant approach to solving this?

This is signature of GetRecords:

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

This is my base implementation:

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
}

I have derived objects based on that base implementation as follows:

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>
{

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我做我的改变 2024-08-17 05:46:32

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

您没有给出 GetRecords<> 的代码方法,但推测 GetRecords 返回 RecordCollection,而不是 PersonCollection(它在代码中的某处有新的 RecordCollection,不是吗?)。

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

这就像

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

Your approach does not work because cast does not convert instances of one class to instances of another class.

You did not give the code of GetRecords<> method, but presumably GetRecords returns RecordCollection, and not PersonCollection (it has new RecordCollection somewhere in the code, doesn't it?).

You cannot cast RecordCollection to PersonCollection unless this particular instance actually is PersonCollection. Presicely because it does not have these additional methods.

This is like

SomeClass obj=new SomeClass();
DerivedClass o=(DerivedClass)obj; //throws exception
治碍 2024-08-17 05:46:32

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

简单的实现可以使用一些 if,否则您可以通过 Dictionary 将具体集合类型与记录类型相关联。

Your best bet is to use some sort of factory call inside GetRecords, so that when you request a 'collection' of Person it will return PersonCollection as RecordCollection<Person>.

A naive implementation can use a few if's, else you can associate concrete collection type to record types via a Dictionary<Type,Type>.

坦然微笑 2024-08-17 05:46:32

一个选项:

将派生类型上的方法设为非扩展静态方法,这些方法接受专门的 RecordsCollection ,即

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

这样您就可以按照以下方式使用

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

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

One option:

Make the methods on the derived types non-extension static methods that take in a specialized RecordsCollection ie

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

so you can have usage along the lines of

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

It's not as pretty as the extension methods, but not too bad either.
edit: Removed erroneous info previously posted and replaced with potential solution

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文