我有一个带有一个参数的方法,它是我创建的类的实例 - Chessfield,它包含三个表 - 一个整数和两个bools。
在方法中我还有Chessfield列表,它是我方法的返回对象。
我正在修改chessfield(所以参考对象)并将其添加到List.Add(Chessfield)列表上几次(每次更改后一次)。
在最终返回对象中(所以列表包含Chessfield的几个对象)所有实例都是相同的,不尊重我的更改!
我已经阅读了类似的主题,并尝试将' ref'在争论之前和我进行这种方法的地方。 如果没有成功,我也尝试在方法中创建Chessfield实例,并从引用中为其分配Chessfield对象,然后对内部创建的对象进行更改。
我怎么解决?最后,我需要接收对象列表,每个对象都是从原始对象(从引用)稍微修改一下。
度过美好的一天!!
P.S。如果代码有用,那么我剪切并粘贴一般的想法代码。
编辑:
Joel undrestand me好!区别在于内部对象是表,它使问题更复杂,因为与这个原始对象相比,我在这些表中做了一些更改。为了更清楚,我粘贴了我的代码:
public class Chessfield
{
public int[] pieces = new int[64];
public bool[] blacks = new bool[64];
public bool[] whites = new bool[64];
public Chessfield(int[] pieces, bool[] blacks, bool[] whites)
{
this.pieces = pieces;
this.blacks = blacks;
this.whites = whites;
}
public Chessfield()
{
}
}
方法看起来像这样:
static public List<Chessfield> MakeAllMovesForWhites(Chessfield chessfieldModel)
{
List<Chessfield> listOfPossibleMoves = new List<Chessfield>(); // list containing chessfields with changed position of figures
int indexOfCurrentPosition = 0; //start with field 0 (most top left)
foreach (bool singleEnemyChecker in chessfieldModel.whites) //iterate all fields, table of whites contain information if white field stand on the field (true, otherwise false),
{
if (singleEnemyChecker == true) //so algorithm will proceed only fields with white figure
{
int kindOfPiece = chessfieldModel.pieces[indexOfCurrentPosition]; // (table pieces contain information which kind of figure stand on particular field 0 -> empty, 1 -> soldier, 2-> tower, 3 -> horse etc...
switch (kindOfPiece)// (based on figure at field it is going to predict all possible moves
{
case 2: // tower case
if (indexOfCurrentPosition % 8 != 0) // check if the field is not most left, otherwise leave
{
int localIndexIterator = indexOfCurrentPosition; //localIndex iterate all possible moves in left direction
while (localIndexIterator % 8 != 0) // checking if tower is standing on the most left field
{
localIndexIterator = localIndexIterator - 1; //iterate all possible moves of tower for left direction
if (chessfieldModel.pieces[localIndexIterator] == 0) //if there are no figures on checking field proceed:
{
chessfieldModel.pieces[indexOfCurrentPosition] = 0; // erase tower from original position
chessfieldModel.whites[indexOfCurrentPosition] = false; // and mark that white tower is not standing there anymore
chessfieldModel.pieces[localIndexIterator] = 2; // put tower on new place
chessfieldModel.whites[localIndexIterator] = true; // and mark that on new place there is white figure
listOfPossibleMoves.Add(chessfieldModel); // here I add changed object of chessfield to list
chessfieldModel.pieces[indexOfCurrentPosition] = 2; // here I come back to original chessfield
chessfieldModel.whites[indexOfCurrentPosition] = true;
chessfieldModel.pieces[localIndexIterator] = 0;
chessfieldModel.whites[localIndexIterator] = false;
}
else //if there is figure at checking field
break; //leave this case
}
}
if (indexOfCurrentPosition % 8 != 7) // right direction case
{
// here is similar code to the sample above
}
if (indexOfCurrentPosition / 8 != 0) //top direction case
{
// here is similar code to the sample above
}
if (indexOfCurrentPosition / 8 != 7) //bottom direction case
{
// here is similar code to the sample above
}
break;
// here are another figures horse and so on...
}
}
indexOfCurrentPosition++; // go to next field...
}
return listOfPossibleMoves; //return list of changed chessfields
}
在这里我称之为方法
Logic.MakeAllMovesForWhites(currentChessfield);
我明白这是什么问题。而乔尔 - 你解释得非常好! (y)谢谢你。
我解决问题的第一个尝试是(在我问这里之前):
Chessfield abc = new Chessfield();
abc = chessfieldModel;
abc.pieces[indexOfCurrentPosition] = 0;
abc.whites[indexOfCurrentPosition] = true;
abc.pieces[localIndexIterator] = 2;
abc.whites[localIndexIterator] = false;
listOfPossibleMoves.Add(abc);
失败。我在每种情况下都尝试过这种方法(为每个图形和每个方向创建)。顺便说一下,有33个不同的情况下,数字如何在国际象棋中移动,所以我在这33个地方上面有这段代码(但有时我把不同的东西放到桌子上......)。但是如果左边没有碎片那么像塔的图可以向左移动1,2,3,4,5,6,7个字段...这是必须创建总是新的实例的问题,我不知道怎么样,因为我必须创建唯一的实例,更改它,并添加到列表..始终是唯一的,但在不同的情况下。
此外,我已经尝试过你的解决方案Joel,但问题是我需要对原始的chessfield进行一些更改(总共4行,但不同的数字会有不同的变化)。 但我尝试创建一个新实例,将其添加到列表中,然后在列表中更改它。即便如此,没有工作和逻辑是不正确的。
listOfPossibleMoves.Add(new Chessfield() { pieces = chessfieldModel.pieces, blacks = chessfieldModel.blacks, whites = chessfieldModel.whites });
listOfPossibleMoves[listOfPossibleMoves.Count - 1].pieces[indexOfCurrentPosition] = 0;
listOfPossibleMoves[listOfPossibleMoves.Count - 1].whites[indexOfCurrentPosition] = false;
listOfPossibleMoves[listOfPossibleMoves.Count - 1].pieces[localIndexIterator] = 2;
listOfPossibleMoves[listOfPossibleMoves.Count - 1].whites[localIndexIterator] = true;
编辑:所以也许回到我的第一个方法,但我如何为在同一个地方创建的对象创建唯一的名称?你可以推荐一些技巧或在这种情况下我能做些什么吗?
感谢Joel和所有:) 每个人都度过美好的一天(或晚上)!
答案 0 :(得分:2)
在问题中查看代码真的很有帮助,但听起来你正在做这样的事情:
public class ChessField
{
public bool b1;
public bool b2;
public int i1;
}
public List<ChessField> Method(ChessField c)
{
var result = new List<ChessField>();
for (int i = 0;i<3;i++)
{
c.i1 = i;
result.Add(c);
}
return result;
}
问题在于:您正在将相同的对象添加到列表中。 result[0]
引用相同的对象实例,result[1]
引用与result[2]
相同的对象实例,引用与c
相同的对象实例。更改c
中的属性会更改此代码中的其他位置,因为它们都是内存中相同对象的变量。如果您需要使对象不同,则必须执行某些操作来创建新的对象实例,如下所示:
public List<ChessField> Method(ChessField c)
{
var result = new List<ChessField>();
for (int i = 0;i<3;i++)
{
result.Add(new ChessField() {b1 = c.b1, b2 = c.b2, i1 = i});
}
return result;
}
或我喜欢的风格会这样做:
public IEnumerable<ChessField> Method(ChessField c)
{
return Enumerable.Range(0, 3)
.Select(i => new ChessField() {b1 = c.b1, b2 = c.b2, i1 = i});
}