从基类列表中返回引用将返回';什么都没有;
本文关键字:返回 什么 列表 基类 引用 | 更新日期: 2023-09-27 18:11:41
我有几个"项"共享类似的功能,因此我从定义公共功能的基类派生它们。
接下来,我还希望有这些项的专门列表,因此我从抽象的基本容器派生类似容器的类。
下面的代码演示了我的问题。
项目
public abstract class QAbstractItem
{
public int xAbstractMember;
public QAbstractItem(int a)
{
xAbstractMember = a;
}
}
public class QSingleItem : QAbstractItem
{
public int xSingleMember;
public QSingleItem(int s, int a) : base(a)
{
xSingleMember = s;
}
}
列表
public abstract class QAbstractItemsList
{
public List<QAbstractItem> xItems = new List<QAbstractItem>();
protected void add(QAbstractItem xItem)
{
xItems.Add(xItem);
}
public void getFirst(QAbstractItem yItem)
{
yItem = xItems[0]; // XXX
}
}
public class QSingleItemsList : QAbstractItemsList
{
public void add(QSingleItem S)
{
base.add(S);
}
}
用法
QSingleItemsList xSingleList = new QSingleItemsList();
xSingleList.add(new QSingleItem(5, 5));
QSingleItem xFirst = new QSingleItem(0,0);
xSingleList.getFirst(xFirst);
代码的最后一行应该(根据我的要求(在xFirst中包含(5,5(。但是,它包含(0,0(。当调试器位于XXX
行时,xItems[0]和yFirst都是(5,5(。当代码返回到调用者(main(时,xFirst突然变成了(0,0(。为什么?
非常感谢您的帮助,Daniel
getFirst
的实现不正确。您需要向其中添加ref或out关键字。ref关键字表示可以重新分配传入的值,out关键字表示忽略输入值并将结果分配到那里。
public void getFirst(ref QAbstractItem yItem)
或
public void getFirst(out QAbstractItem yItem)
然后它会像这样被称为
QAbstractItem xFirst = new QSingleItem(0,0);
xSingleList.getFirst(ref xFirst);
让它发挥作用,但实际上它应该更接近
public QAbstractItem getFirst()
public void getFirst(QAbstractItem yItem)
{
yItem = xItems[0]; // XXX
}
yItem
参数是按值传递的(即使它是引用类型;引用也是按值传递(。因此,当您为yItem赋值时,调用者不会受到影响,因为yItem
只包含原始引用的副本。要使其工作,您需要通过引用传递yItem
:
public void getFirst(ref QAbstractItem yItem)
{
yItem = xItems[0]; // XXX
}
但是,在这种情况下,您将无法使用类型为QSingleItem
的参数来调用它。
您的问题的另一种解决方案是使列表类通用:
public class QItemsList<TItem> where TItem : QAbstractItem
{
public List<TItem> xItems = new List<TItem>();
protected void add(TItem xItem)
{
xItems.Add(xItem);
}
public void getFirst(out TItem yItem)
{
yItem = xItems[0]; // XXX
}
}
如果您需要针对给定类型的项的专用方法,可以将它们添加到继承泛型列表的类中:
public class QSingleItemsList : QItemsList<QSingleItem>
{
// specialized methods here
}
问题出在该方法中:
public void getFirst(QAbstractItem yItem)
{
yItem = xItems[0]; // XXX
}
您必须注意,当您将参数传递给方法时,会创建对yItem
的引用的副本。因此,如果将新值分配给yItem
,它对传递给方法getFirst
的实际参数没有影响。根据C#规范,这是正确的行为。
您可以考虑更改方法以返回第一个元素:
public QAbstractItem getFirst()
{
return xItems[0]; // XXX
}