c#中接收方的有效返回值变为空
本文关键字:返回值 有效 | 更新日期: 2023-09-27 18:13:32
我刚开始接触c#,所以如果这是一个基本问题,请原谅我。我正在使用。net 4.0和VS 2010构建一个WPF应用程序。
我有一个类,我在其中存储对象的List
;对象有一个Point对象作为字段。其中一个方法返回列表中特定位置的对象:
public Marker markerAtLocation(Point location) {
foreach (Marker nextMarker in Markers)
if (nextMarker.Location().Equals(location))
return nextMarker;
return null;
}
设置断点并使用Console.WriteLine
,我已经确认nextMarker
在返回时有效。然而,在接收器中,对象总是null
:
Marker top = markerAtLocation(new Point(location.X, location.Y + 1));
if (top == null)
Console.WriteLine("Top is null");
else
Console.WriteLine("Top is " + top.ToString());
Marker bottom = markerAtLocation(new Point(location.X, location.Y - 1));
if ((bottom != null) && (bottom.player == otherPlayerType()) && (top != null) && (top.player == otherPlayerType()))
return true;
我不知道这是怎么回事…
请注意,我最初认为这是。net的Point
结构体使用双精度值的问题。我知道在我的应用程序中的位置值将始终是整数,所以我没有使用。net Point和创建我自己的:
class Point {
public int X, Y;
public Point(int X, int Y) {
this.X = X;
this.Y = Y;
}
public bool Equals(Point anotherPoint) {
return ((anotherPoint.X == X) && (anotherPoint.Y == Y));
}
}
我很感激任何帮助!
编辑:回应pbirkoff:
class Grid {
public List<Marker> Markers;
public Grid() {
Markers = new List<Marker>();
}
public Grid(List<Marker> markers) {
this.Markers = markers;
}
public void addMarker(Marker newMarker) {
Markers.Add(newMarker);
}
我已经尽我所能尝试了下面的解决方案,但没有一个有用。我包括一个链接到项目本身以及我试图解决的问题。
项目:http://dl.dropbox.com/u/7828009/ACSLPetteia.zip
问题:http://wcipeg.com/etc/ACSL/VOL%2030/ACSL%20Petteia_sr_3.doc
提前感谢!
我尽可能简洁地实现了您的代码,在适当的地方做了一些模拟(下面的代码),我不能让它失败。我的代码示例中缺少什么:
class Program
{
static void Main(string[] args)
{
LoadMarkers();
var location = new Point(45, 45);
Marker top = markerAtLocation(new Point(location.X, location.Y + 1));
if (top == null)
Console.WriteLine("Top is null");
else
Console.WriteLine("Top is " + top.ToString());
Marker bottom = markerAtLocation(new Point(location.X, location.Y - 1));
}
public static List<Marker> Markers = new List<Marker>();
private static void LoadMarkers()
{
for (var q = 0; q < 50; q++)
for (var w = 0; w < 50; w++)
Markers.Add(new Marker(q, w));
}
public static Marker markerAtLocation(Point location)
{
foreach (Marker nextMarker in Markers)
if (nextMarker.Location().Equals(location))
return nextMarker;
return null;
}
}
class Marker
{
private Point _loc;
public Marker(int x, int y) { _loc = new Point(x, y); }
public Point Location() { return _loc; }
}
class Point
{
public int X, Y;
public Point(int X, int Y)
{
this.X = X;
this.Y = Y;
}
public bool Equals(Point anotherPoint)
{
return ((anotherPoint.X == X) && (anotherPoint.Y == Y));
}
}
我将首先从更改类的名称开始。名称空间通常会处理任何冲突,但WPF点在System中定义。当尝试在WPF窗口类中创建Point时,Windows很可能会导致问题,我猜这是您的接收器代码所在的位置。我这么说的原因是,默认情况下,在自动生成的windows类VS创建的顶部会有一行"using System.Windows;"。
由于所有内容都派生自object,因此您也需要重写bool Equals(object o)函数,因为这将帮助您捕获与System.Windows.Point而不是您的Point进行比较的问题。
我想如果你把你的类名改为IntPoint,你可能会发现你的接收代码中的"new Point"可能不会被重构为"new IntPoint",因为它可能被解析为System.Windows.Point.
使用Grid作为名称也是如此。我尽量坚持不使用与。net类型名称匹配的类型名称的惯例,以避免奇怪的冲突。
所以总结一下,把你的类改成如下:class IntPoint {
public int X { get; set; }
public int Y { get; set; }
public IntPoint(int X, int Y) {
this.X = X;
this.Y = Y;
}
public override bool Equals(object obj)
{
if (obj is IntPoint) return Equals(obj as IntPoint);
return base.Equals(obj);
}
public bool Equals(IntPoint anotherPoint) {
return ((anotherPoint.X == X) && (anotherPoint.Y == Y));
}
}
我还使用速记默认get/set语法将公共字段更改为公共属性。我不会深入到属性和字段的细节,但你可以在网上搜索。net属性和公共字段。部分原因与绑定的工作方式有关,. net允许您绑定到属性,但如果您试图绑定到其中一个字段,我相信它将无法找到它们。
如果你做了这些修改,但仍然不能正常工作,请发回。
可能与花括号有关(使用它们时可读性更强),尽管这可能不太可能。如果您将一个局部变量声明为函数的持有人,并返回该变量的存储值,该怎么办?这是否解决了问题,还是仍然表现出相同的行为?例如:
public Marker markerAtLocation(Point location) {
Marker returnMarker = null;
foreach (Marker nextMarker in Markers) {
if (nextMarker.Location().Equals(location)) {
returnMarker = nextMarker;
break;
} // end if
} // end foreach
return returnMarker;
} // end function
您是否100%肯定markerAtLocation返回非空标记。在调试中,你看到那行叫做??不,你没有看到它调用那行,因为你有它结构化调试的方式没有一行停下来看它"返回nextMarker()。这里有3层逻辑,没有{}。您确定您的代码像您期望的那样运行吗?
foreach (Marker nextMarker in Markers)
if (nextMarker.Location().Equals(location))
return nextMarker;
return null;
我怀疑发生了什么循环只到第二行。在最后且仅在最后一行,它继续返回nextMarker,并且只有当匹配在最后一行时才为真。清理你的逻辑——这不会有坏处。
foreach (Marker nextMarker in Markers)
{
if (nextMarker.Location().Equals(location))
{
return nextMarker;
}
}
return null;
我认为我们需要更多的信息(如Jon所要求的)来确定这里到底出了什么问题。
也许您正在使用静态函数并引用非静态项,例如您的公共类成员。这仍然可以编译和运行,尽管非静态变量在使用之前不会被初始化或设置。
最好将公共类变量实现为属性,例如public List<Marker> Markers{get;set;}
而不是public List<Marker> Markers
。Point类中的X和Y也是如此。
我的直觉是,你的一些类实例不再在范围内,或者因为它们是公共变量,它们可能已经被覆盖-尝试定义它们volatile
-到你来引用它们的时候。