【问题标题】:Passing References传递参考
【发布时间】:2011-08-16 04:11:41
【问题描述】:

我想知道一种在类之间传递引用的好方法。

基本上我的检查代码中有两个类:

一个是棋盘游戏代码..

        class CheckersCode
    {
        IchecherMove[,] pieces;
        public static int counter;
        Checkers checker;
        public void ExecuteAll(int columnStart, int rowStart, int columnEnd, int rowEnd)
        {              
            checker = new Checkers();
            Game g=new Game(pieces, columnStart, rowStart,  columnEnd, rowEnd);// i want this reference to be passed in the method below
            g.MoveValidityManager();
            checker.obtainGameReference(g);//i want this reference to be passed through this method

其他代码是表单代码:

    public partial class Checkers : Form
{
    public Checkers()
    {
        InitializeComponent();
    }
    CheckersCode codeFile = new CheckersCode();

    private void Checkers_Load(object sender, EventArgs e)
    {
        chessPics = Pattern();
        PrintPieces(codeFile.FirstLoad());        
    }
    Game gameRef;
    public void obtainGameReference(Game g)// i want that reference to be obtained here
    {
        gameRef=g;and be passed to this
    }

问题是那不起作用..当我使用 gameRef 引用时,它会抛出一个空点异常,例如gameRef.piecePromotion(); // nullerpointException

好的,我更新了我的问题:

如果我将对象引用设为静态,它会起作用:

public static Game gameRef; 

但不是:

 public Game gameRef; 

发生的事情是 私人无效a1_Click(对象发送者,EventArgs e) { codeFile.ExecuteAll(rowStart, columnStart, rowEnd, columnEnd);// 每次我决定将一块移动到新的图片框时都会执行此操作。 gameRef.piecePromotion();// 下一步执行。 } 由于 Game 的 gameRef 不是静态的,在 ExcuteAll 方法执行一次后,gameRef 变为 null(而在它完成执行之前,它被分配)。

这里是 ExecuteAll 方法:

 public void ExecuteAll(int columnStart, int rowStart, int columnEnd, int rowEnd)
            {              
                checker = new Checkers();
                Game g=new Game(pieces, columnStart, rowStart,  columnEnd, rowEnd);
                checker.obtainGameReference(g);

                g.MoveValidityManager();// calls a method for a class to be executed. no new instances of Checkers class are being created , inside the game class.

它以某种方式通过代码将 gameRef 重置为 null。所以我检查了整个代码,如果我创建了 Checkers 类型的新对象(我的 winform 部分类)..但是单击 ctrl+F ..我发现只有一个实例在其中创建了对象引用。

为什么它在为它分配对象引用之后将gameRef重置为null

我只在事件中使用 gameRef...我只实例化 Game 类和 CheckerCode 类一次 ..并且我不会通过代码杀死引用。我的引用仅在图片框点击事件中激活:

        private void a2_Click(object sender, EventArgs e)
    {
        if (NextTurn)
        {
            columnEnd = 1;
            rowEnd = 2;
            codeFile.ExecuteAll(rowStart, columnStart, rowEnd, columnEnd);// it does assign the gameRef throughout the method, but at the end....
            gameRef.piecePromotion();// this is reset to null after the above method finishes executing

        }

我在调试模式下查看了代码..

        public void obtainGameReference(Game g)
    {
        gameRef=g;// g is not null, it contains the object. gameRef remains a null.
    }

因此当代码继续运行几步之后。在表单类/文件(检查器)中

       gameRef.piecePromotion(); // gameRef is null

【问题讨论】:

  • 你的代码没问题。问题一定出在其他地方。请显示您在哪里使用 gameRef。
  • Checkers是您的主应用程序窗口吗?
  • 您是否可能在 Checkers 类的某处处置或重新分配 codeFile 实例?
  • codeFile 正在整个部分类中使用。它没有被处置。事件方法包含两个方法并排在一起 codeFile.ExecuteAll 和 gameRef.piecePromotion

标签: c# object reference


【解决方案1】:

在某些时候,gameRef 似乎在设置之前被使用,或者被设置为 null。

由于没有一个类就没有任何意义,我总是让类的一部分不变量(必须始终为真的一组条件),并在构造函数中强制执行:

private readonly Game _game;//doesn't HAVE to be readonly, but can simplify things if it is
public Checkers(Game game)
{
  if(game == null)
    throw new ArgumentNullException();
  _game = game;
  InitializeComponent();
}

我也很好奇您为什么要明确谈论“参考”。虽然正确,但由于对象始终是引用,因此在 C# 语言中这样谈论它们是不寻常的。这让我想知道 Game 是否可能是一个结构,在这种情况下其他事情会出错(您可以持有对结构的引用,但不值得维护它所需的额外工作)。

【讨论】:

  • 实际上,我第一次成功传递了一个对象。从调试中我可以看到,方法 gainGameReference(Game g) 被激活了两次,第二次被设置为 null .. :( ,我需要看看为什么
  • 将它作为类不变量的一部分并在构造函数中设置的另一个原因。
【解决方案2】:

默认情况下,.NET 将通过引用传递引用类型。你确定我们的 pricePromotion 对象中没有空指针吗?

【讨论】:

  • Piece Promotion是Game对象内部的一个方法。
猜你喜欢
  • 1970-01-01
  • 2010-12-12
  • 2011-08-03
  • 1970-01-01
  • 2019-12-28
  • 2011-12-15
  • 2016-04-11
  • 2015-02-06
  • 2014-02-10
相关资源
最近更新 更多