gpt4 book ai didi

C# Generic List of Multiple Types 泛型列表

转载 作者:可可西里 更新时间:2023-11-01 08:16:53 25 4
gpt4 key购买 nike

这是我的问题的抽象和简化:

我有一套玩具和这些玩具对应的盒子。我希望用户能够指定盒子可以容纳的最大类型的玩具:

public class Box<T> {}

然后在 Box 类中我想要一个通用的玩具列表,但是盒子中包含的每个玩具都有一个通用类型:

public class Box<T>
{
public List<Toy> = new List<Toy>();
public bool Whatever;

[member functions, constructors...]
[The member functions will depend on T]
}

Toys 类将如下所示:

public class Toy<T> where T : struct //T is any type
{
public List<T> = new List<T>();
public string Name;
public string Color;

[member functions, constructors...]
}

我希望能够创建具有多种不同类型的 Toys,然后将它们插入具有另一种指定类型的 Box 中。然后我希望能够将盒子加在一起,返回最大类型的盒子。

我真的不知道如何开始。具有多种类型的泛型类的列表真的让我陷入困境。我阅读了各种关于使用抽象类或接口(interface)的文章,但没有找到一个示例或任何可以完成与我正在尝试做的事情类似的东西。

任何人都可以提供任何帮助,我们将不胜感激。

解决方案可以在 C# 4.0 中。

可能的 future 澄清:

我希望 Toy 是通用的并在实例化时接受参数,因为 Toy 还必须有一个 List 作为成员。

Toy 中的嵌套列表是我的主要问题。然后我想要一个包含玩具的 Box 列表,但每个玩具都有不同的类型构造函数。

更新:

我修复了 Box to Box 的错别字。

更新 2:

Toy<plastic> tyPlastic = new Toy<plastic>("Name1", Blue, new plastic[] {0xFFEE00, 0xF34684, 0xAA35B2});
Toy<wood> tyWood = new Toy<wood>("Name2", Grain, new wood[] {a1, f4, h7});

Box<plastic> bxBox = new Box<plastic>();//The Box has the ability to hold both plastic and wood toys. Plastic > Wood > Paper

最后:我最终删除了 Box 通用的要求。然后我使用反射来创建动态类型的玩具。谢谢大家。

最佳答案

如果您正在构建的代码能够很好地模拟现实,那么您将能够更好地理解它。

建模“A of B”的方法是使用泛型。一组可以容纳一种东西的盒子将建模为 Box<T> .一个只能装玩具的盒子是 Box<Toy> .一组可以容纳一种东西的盒子,而那个东西必须是玩具将是 Box<T> where T : Toy .

到目前为止一切顺利。但是Toy<T>的概念不映射到现实生活中的任何东西。您可能有一盒 cookies 或一盒玩具,但您没有 cookies 玩具、洋娃娃玩具或长颈鹿玩具。 “玩具”这个概念没有任何意义,所以不要模拟它

一个更明智的模型是“有一类叫做玩具的东西。没有任何东西只是玩具;每个玩具都是一种更具体的玩具。球是玩具。A娃娃是玩具。”所以建模:

abstract class Toy {}
class Doll : Toy {}
class Ball : Toy {}

你说

I want Toy to be generic and accept a argument at instantiation because Toy must also have a List as a member.

为什么? 玩具没有东西 list 。所以不要建模。相反,一个盒子在逻辑上被建模为盒子内玩具的列表。 (或者,由于一个盒子通常不应用排序,并且一个盒子只包含独特的玩具,也许一套玩具会更好。)

I want to be able to create Toys with many different types and then insert them into a Box with another specified type.

好的。所以对 Box<T> 进行操作是void Insert(T item) .你可以把一个玩具放进一盒玩具里,你可以把一个洋娃娃放进一盒洋娃娃里,但你不能把一个球放进一盒洋娃娃里。

Then I'd like to be able to add boxes together returning a Box with the largest type.

您需要更仔细地定义“最大类型”。如果将一盒洋娃娃加到一盒球上,显然结果既不是一盒球也不是一盒洋娃娃。结果是一盒玩具。

下面是我将如何对此进行建模。我们已经有了玩具层次结构。我会继续说,T 的一个盒子被实现为其内容的集合,并提供其内容的序列。

// Haven't actually compiled this.
class Box<T> : IEnumerable<T>
{
private HashSet<T> set = new HashSet<T>();
public Insert(T item) { set.Add(item); }
public IEnumerator<T> GetEnumerator() { return set.GetEnumerator(); }
public IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); }

到目前为止一切都很无聊。现在我们来到有趣的地方。 这只适用于 C# 4

    public static Box<T> MergeBoxes(IEnumerable<T> box1, IEnumerable<T> box2)
{
Box<T> box = new Box<T>();
foreach(T item in box1) box.Insert(item);
foreach(T item in box2) box.Insert(item);
return box;
}
}

现在你可以说

Box<Doll> dollbox = new Box<Doll>() { new Doll() };
Box<Ball> ballbox = new Box<Ball>() { new Ball() };
Box<Toy> toybox2 = Box<Toy>.MergeBoxes(ballbox, dollbox);

将一盒玩偶与一盒球合并的结果是一盒玩具。

这最后一点只有效,因为 IEnumerable<T>在 C# 4 中是协变的。在 C# 3 中,要做到这一点会比较棘手;你必须做类似的事情:

Box<Toy> toybox2 = Box<Toy>.MergeBoxes(ballbox.Cast<Toy>(), dollbox.Cast<Toy>());

这有意义吗?

关于C# Generic List of Multiple Types 泛型列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2075866/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com