C# 从基类列表返回引用将返回';没有';
我有几个共享类似功能的“项”,因此我从定义公共功能的基类派生它们 接下来,我还希望有这些项目的专门列表,因此我从抽象的基本容器派生类似容器的类 下面的代码演示了我的问题 项目C# 从基类列表返回引用将返回';没有';,c#,abstract-class,derived-class,C#,Abstract Class,Derived Class,我有几个共享类似功能的“项”,因此我从定义公共功能的基类派生它们 接下来,我还希望有这些项目的专门列表,因此我从抽象的基本容器派生类似容器的类 下面的代码演示了我的问题 项目 public abstract class QAbstractItem { public int xAbstractMember; public QAbstractItem(int a) { xAbstractMember = a; } } public class QS
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);
}
}
列表
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);
}
}
最后一行代码应该(正如我所希望的)包含xFirst中的(5,5)。但是,它包含(0,0)。当调试器联机时,xItems[0]和yFirst都是(5,5)。当代码返回到调用方(main)时,xFirst突然变为(0,0)。为什么?
非常感谢您的帮助,
丹尼尔
yItem
参数按值传递(即使它是引用类型;引用按值传递)。因此,当您为yItem赋值时,调用者不会受到影响,因为yItem
只包含原始引用的副本。要使其工作,您需要通过引用传递yItem
:
public void getFirst(ref QAbstractItem yItem)
{
yItem = xItems[0]; // XXX
}
但是,在本例中,您将无法使用类型为QSingleItem
的参数调用它
您的问题的另一个解决方案是将list类设置为泛型:
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
}
}
公共类QItemsList,其中TItem:QAbstractItem
{
public List xItems=新列表();
受保护的无效添加(TItem xItem)
{
xItems.Add(xItem);
}
公共无效getFirst(out TItem yItem)
{
yItem=xItems[0];//XXX
}
}
如果给定类型的项需要专用方法,可以将它们添加到继承泛型列表的类中:
public class QSingleItemsList : QItemsList<QSingleItem>
{
// specialized methods here
}
公共类QSingleItemsList:QItemsList
{
//这里有专门的方法
}
yItem
参数按值传递(即使它是引用类型;引用按值传递)。因此,当您为yItem赋值时,调用者不会受到影响,因为yItem
只包含原始引用的副本。要使其工作,您需要通过引用传递yItem
:
public void getFirst(ref QAbstractItem yItem)
{
yItem = xItems[0]; // XXX
}
但是,在本例中,您将无法使用类型为QSingleItem
的参数调用它
您的问题的另一个解决方案是将list类设置为泛型:
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
}
}
公共类QItemsList,其中TItem:QAbstractItem
{
public List xItems=新列表();
受保护的无效添加(TItem xItem)
{
xItems.Add(xItem);
}
公共无效getFirst(out TItem yItem)
{
yItem=xItems[0];//XXX
}
}
如果给定类型的项需要专用方法,可以将它们添加到继承泛型列表的类中:
public class QSingleItemsList : QItemsList<QSingleItem>
{
// specialized methods here
}
公共类QSingleItemsList:QItemsList
{
//这里有专门的方法
}
您对getFirst
的实现不正确。您需要向其中添加ref或out关键字。关键字表示可以重新分配传入的值,关键字表示忽略输入值,结果将分配到那里
public void getFirst(参考qabstractem yItem)
或
public void getFirst(out qabstractem yItem)
然后它会被这样称呼
QAbstractItem xFirst = new QSingleItem(0,0);
xSingleList.getFirst(ref xFirst);
让它工作,但实际上它应该更接近
public QAbstractItem getFirst()
您对getFirst
的实现不正确。您需要向其中添加ref或out关键字。关键字表示可以重新分配传入的值,关键字表示忽略输入值,结果将分配到那里
public void getFirst(参考qabstractem yItem)
或
public void getFirst(out qabstractem yItem)
然后它会被这样称呼
QAbstractItem xFirst = new QSingleItem(0,0);
xSingleList.getFirst(ref xFirst);
让它工作,但实际上它应该更接近
public QAbstractItem getFirst()
该方法存在问题:
您必须知道,当您将参数传递给方法时,将创建对yItem
的引用的副本。因此,如果将新值赋给yItem
,它对传递给方法getFirst
的实际参数没有影响。
根据C#规范,这是正确的行为
可以考虑更改方法返回第一个元素:
问题在于这种方法: 您必须知道,当您将参数传递给方法时,将创建对
yItem
的引用的副本。因此,如果将新值赋给yItem
,它对传递给方法getFirst
的实际参数没有影响。
根据C#规范,这是正确的行为
可以考虑更改方法返回第一个元素:
正如Thomas Levesque指出的那样,ref/out的问题在于它不适用于抽象类。对于实际应用程序中的
public QAbstractItem getFirst()
,我需要获得一对特定的qsingleItem,因此我在参数中“返回它们”。@DanielBencik返回包含这对对象的对象可能比使用out
/ref
@DanielBencik如果您失去了我,getFirst只给你一件事。您的意思是要将它们作为类型QSingItem
而不是作为QAbstractItem
获取吗?@Sign:是的,getFirst是为演示而编写的。实际上,我希望有类似于getSomeTwo()
,即我需要返回一对特别选择的qsingleitem.\@DanielBencik那么为什么不返回一个元组呢?或者其他更具体的东西同时包含这两者?ref/out的问题是它不能处理抽象类,正如Thomas Levesque也指出的那样。对于实际应用程序中的public qabstracttem getFirst()
,我需要获得一个特定的对