C# 在C中创建对象的通用列表#
通过介绍,我创建了一个基本的四叉树引擎,用于个人学习。我希望这个引擎能够处理许多不同类型的形状(目前我使用的是圆和正方形),这些形状都会在窗口中移动,并在发生碰撞时执行某种操作 以下是我目前拥有的形状对象:C# 在C中创建对象的通用列表#,c#,list,generics,object,quadtree,C#,List,Generics,Object,Quadtree,通过介绍,我创建了一个基本的四叉树引擎,用于个人学习。我希望这个引擎能够处理许多不同类型的形状(目前我使用的是圆和正方形),这些形状都会在窗口中移动,并在发生碰撞时执行某种操作 以下是我目前拥有的形状对象: public class QShape { public int x { get; set; } public int y { get; set; } public string colour { get; set; } } public class QCircle
public class QShape {
public int x { get; set; }
public int y { get; set; }
public string colour { get; set; }
}
public class QCircle : QShape {
public int radius;
public QCircle(int theRadius, int theX, int theY, string theColour) {
this.radius = theRadius;
this.x = theX;
this.y = theY;
this.colour = theColour;
}
}
public class QSquare : QShape {
public int sideLength;
public QSquare(int theSideLength, int theX, int theY, string theColour) {
this.sideLength = theSideLength;
this.x = theX;
this.y = theY;
this.colour = theColour;
}
}
现在我的问题是,如何在C#中创建一个通用列表(list QObjectList=new list();
),这样我就可以有一个包含所有这些不同形状的列表,这些形状可能具有不同的属性(例如,QCircle具有“radius”属性,而QSquare具有“sideLength”属性)?一个实施的例子也会有帮助
我只知道这个问题有一个愚蠢而明显的答案,但无论如何我都会感谢任何帮助。我想回到C#;显然已经有一段时间了…我觉得我错过了什么,但是
List<QCircle> circleObjects = new List<QCircle>();
值得注意的是,如果您想访问该列表中所有
QCircle
的radius
属性,则必须根据类型筛选列表。您可以使用Ian Mercer的注释list
下面是您将如何填充它:
List<QShape> shapes = new List<QShape>();
QCircle circle = new QCircle();
shapes.Add(circle);
如果您需要从基类调用一个方法,无需取消装箱,只需使用它。您需要使用向下转换 将对象存储在具有基类的列表中
List<QShape> shapes = new List<QShape>
您还可以隐式向下投射对象
QSquare square = new Square(5,0,0,"Blue");
QShape shape = square
您应该实现一个
接口。比如说
public interface IHasLength
{
int Length;
}
然后在实现中,您可以执行以下操作
public class QSquare : QShape, IHasLength {
public int sideLength;
public QSquare(int theSideLength, int theX, int theY, string theColour) {
this.sideLength = theSideLength;
this.x = theX;
this.y = theY;
this.colour = theColour;
}
public int Length { get { return sideLength; } }
}
public class QCircle : QShape, IHasLength {
public int radius;
public QSquare(int theSideLength, int theX, int theY, string theColour) {
this.sideLength = theSideLength;
this.x = theX;
this.y = theY;
this.colour = theColour;
}
public int Length { get { return radius; } }
}
最后,在您的列表中:
List<IHasLength> shapesWithSomeLength = new List<IHasLength>();
List shapesWithSomeLength=newlist();
现在,您的列表可以容纳实现IHasLength
的任何内容,无论是QCircle
、QShape
,甚至是QDuck
,只要它实现IHasLength,您就可以将它们存储在列表中,但这意味着您无法访问特定于类型的属性
通常,您可以通过在基类中提供一个公共接口并重写子类中的行为来实现这一点。通过这种方式,公共接口可以隐藏多种行为。例如,Grow
方法可以隐藏不同形状的增长项的复杂性,并且可以在不明确了解其操作形状的情况下调用该方法
public abstract class QShape {
public abstract void Grow(int amt);
}
public class QSquare : QShape {
private int sideLength;
public override void Grow(int amt)
{
sideLength+=amt;
}
}
public class QCircle : QShape {
private int radius;
public override void Grow(int amt)
{
radius+=amt;
}
}
储存
您的类定义已经走上了正确的轨道。您需要做的是创建一个超类的列表
(在本例中为QShape
),它将能够容纳您的所有形状
下面是一个示例,说明您将如何做到这一点:
List<QShape> objects = new List<QShape>();
objects.add(new QCircle(...));
objects.add(new QSquare(...));
完成此操作后,可以继续使用对象,如普通对象。但是,如果您尝试从列表中访问它们,则只能使用QShape
拥有的方法和变量,因为列表中的每个对象都将被强制转换为它。这就是您想要的吗
public class QShape
{
protected QShape() { }
public int x { get; set; }
public int y { get; set; }
public string colour { get; set; }
}
public class QCircle : QShape
{
public int radius;
public QCircle(int theRadius, int theX, int theY, string theColour)
{
this.radius = theRadius;
this.x = theX;
this.y = theY;
this.colour = theColour;
}
}
public class QSquare : QShape
{
public int sideLength;
public QSquare(int theSideLength, int theX, int theY, string theColour)
{
this.sideLength = theSideLength;
this.x = theX;
this.y = theY;
this.colour = theColour;
}
}
class Program
{
static void Main(string[] args)
{
List<QShape> list = new List<QShape>();
list.Add(new QCircle(100, 50, 50, "Red"));
list.Add(new QCircle(100, 400, 400, "Red"));
list.Add(new QSquare(50, 300, 100, "Blue"));
foreach (var item in list.OfType<QCircle>())
{
item.radius += 10;
}
foreach (var item in list.OfType<QSquare>())
{
item.sideLength += 10;
}
}
}
公共类QShape
{
受保护的QShape(){}
公共整数x{get;set;}
公共整数y{get;set;}
公共字符串颜色{get;set;}
}
公共类QCircle:QShape
{
公共整数半径;
公共QCircle(int theRadius、int theX、int thee、string thecolor)
{
这个半径=theRadius;
这个.x=theX;
this.y=它们;
这个颜色=颜色;
}
}
公共类QSquare:QShape
{
公共内边长;
公共QSquare(整数等长、整数X、整数他们、字符串颜色)
{
此。边长=边长;
这个.x=theX;
this.y=它们;
这个颜色=颜色;
}
}
班级计划
{
静态void Main(字符串[]参数)
{
列表=新列表();
添加(新的QCircle(100,50,50,“红色”);
添加(新的QCircle(100400400,“红色”);
添加(新的QSquare(50、300、100,“蓝色”);
foreach(list.OfType()中的变量项)
{
项目半径+=10;
}
foreach(list.OfType()中的变量项)
{
项目。边长+=10;
}
}
}
公共类抽象基
{
公共摘要ListGetList();
}
那就这样做吧
public class className:Base<ObjectName>
{
public override List<T>GetList()
{
//do work here
}
}
公共类类名:Base
{
公共覆盖ListGetList()
{
//你在这里工作吗
}
}
List??这样的列表会包括从QShape继承的类吗?如果是这样,我是对的;答案是非常明显的。@Djentleman:是的。但是,除非您强制转换单个对象,否则您只能访问QShape属性。我能否以应答形式获得该属性,包括您如何实现该属性的示例(即,如何从列表中访问QCircle和QSquare特定属性)?@Djentleman您不能。不知道为什么他的评论会被高估。您明确声明要访问不包含在父类中的不同属性,因此使用基类作为类型将不起作用。OP需要一个包含这两个属性的列表。因此,它将是列表。是的,这将起作用,但他想要一个列表来容纳任何类型的QShape
,QCircle
,和QSquare
。我应该更清楚,但如果可能的话,我想要一个列表。如果你在处理通用集合中的项目时必须测试类型和强制转换,这是出现问题的迹象。我不太清楚你的意思,它是访问特定类型属性的接口的替代品。我相信你可以在你的示例中使用is关键字,它已经有相当一段时间了。如果(myObject是MyType)@ChrisGessler谢谢,我不知道。我在这个网站上也学到了很多我不知道的东西。。。事实上,每天我都在想我学到了一些新的东西。另外,我在您的示例中没有看到接口的使用,我使用术语接口是一种松散的方式。通过提供方法和属性,所有对象都有一个接口。。。不仅仅是那些继承人
public abstract class QShape {
public abstract void Grow(int amt);
}
public class QSquare : QShape {
private int sideLength;
public override void Grow(int amt)
{
sideLength+=amt;
}
}
public class QCircle : QShape {
private int radius;
public override void Grow(int amt)
{
radius+=amt;
}
}
List<QShape> objects = new List<QShape>();
objects.add(new QCircle(...));
objects.add(new QSquare(...));
if(objects.get(some_position).getType() == typeof(QCircle))
QCircle circle = objects.get(some_position);
else if(/* like above with QSquare */)
QSquare square = objects.get(some_position);
public class QShape
{
protected QShape() { }
public int x { get; set; }
public int y { get; set; }
public string colour { get; set; }
}
public class QCircle : QShape
{
public int radius;
public QCircle(int theRadius, int theX, int theY, string theColour)
{
this.radius = theRadius;
this.x = theX;
this.y = theY;
this.colour = theColour;
}
}
public class QSquare : QShape
{
public int sideLength;
public QSquare(int theSideLength, int theX, int theY, string theColour)
{
this.sideLength = theSideLength;
this.x = theX;
this.y = theY;
this.colour = theColour;
}
}
class Program
{
static void Main(string[] args)
{
List<QShape> list = new List<QShape>();
list.Add(new QCircle(100, 50, 50, "Red"));
list.Add(new QCircle(100, 400, 400, "Red"));
list.Add(new QSquare(50, 300, 100, "Blue"));
foreach (var item in list.OfType<QCircle>())
{
item.radius += 10;
}
foreach (var item in list.OfType<QSquare>())
{
item.sideLength += 10;
}
}
}
public Class abstract Base<T>
{
public abstract List<T>GetList();
}
public class className:Base<ObjectName>
{
public override List<T>GetList()
{
//do work here
}
}