【问题标题】:Method that always return null总是返回 null 的方法
【发布时间】:2020-08-16 06:40:19
【问题描述】:

我被一段从 Java 翻译成 C# 的代码卡住了。

基本上,我有一个 Map(Dictionary),其键由 Pair 组成,而 Values 由我创建的类 (Square) 表示;在这个类中只有一个字段,即 Optional(是的,我在 C# 中创建了 Optional 类)。

一开始我用对填充这个字典来创建一个类似网格和空的可选,你可以在下面的代码中看到。

class World
{
    private Dictionary<Pair<int, int>, Square> map = 
        new Dictionary<Pair<int, int>, Square>();

    public World(int width, int height)
    {
        this.size = new Pair<int, int>(width, height);
        for (int w = 0; w < this.size.GetX(); w++)
        {
            for (int h = 0; h < this.size.GetY(); h++)
                this.map.Add(new Pair<int, int>(w, h), 
                    new Square(Optional<Entity>.Empty()));
        }
    }
}

这是 Square 类

class Square
{
    private Optional<Entity> entity;

    public Square (Optional<Entity> entity)
    {
        this.entity = entity;
    }

    public Optional<Entity> GetEntity() 
    {
        return this.entity;
    }

    public void SetEntity(Optional<Entity> entity)
    {
        this.entity = entity;
    }
}

这就是问题所在,当我尝试从 Dictionary 获取现有值时,always 下面的这个函数返回 null,它抛出 System.NullReferenceException: Object reference not set to an object of an instance。 在这段代码中,我删除了所有控件,但我知道我试图获取一个已经插入的值;另外,我尝试运行 Dictionary.ContainsValue 并返回 false!但我确实已经初始化了字典。

public Square? GetSquare(int x, int y)
{
    if (y < this.size.GetY() && y >= 0 && < x this.size.GetX() && x >= 0)
    {
        this.map.TryGetValue(new Pair<int, int>(x, y), out Square? square);
        return square;
    }

    throw new InvalidOperationException("no square in this position!");
}

我也将 Optional 类的代码留在这里,但我几乎 100% 确定这不是问题

public class Optional<T>
{
    private T value;
    public bool IsPresent { get; set; } = false;

    private Optional() { }

    public static Optional<T> Empty()
    {
        return new Optional<T>();
    }

    public static Optional<T> Of(T value)
    {
        Optional<T> obj = new Optional<T>();
        obj.Set(value);
        return obj;
    }

    private void Set(T value)
    {
        this.value = value;
        this.IsPresent = true;
    }

    public T Get()
    {
        return value;
    }
}

这是对类

    public class Pair<X, Y>
    {
        private X first;
        private Y second;

        public Pair(X first, Y second)
        {
            this.first = first;
            this.second = second;
        }
        public X GetX()
        {
            return this.first;
        }

        public Y GetY()
        {
            return this.second;
        }

        public override string ToString()
        {
            return "<" + first + "," + second + ">";
        }
    }

【问题讨论】:

  • 什么是Pair&lt;,&gt;?它可能有一个糟糕的GetHashCodeEquals 实现。对键使用值元组可能会更好(即(int, int))。
  • 使用this.map.TryGetValue(new Pair&lt;int, int&gt;(x, y), out Square? square); 你永远不会得到任何结果,除非Pair 是一个结构类型。我很确定这在 Java 中也行不通。查看该行中的逻辑:“给我与此 new 对象关联的值” - 由于此对象是新对象,因此不会有任何值与之关联
  • new Pair&lt;int, int&gt;(x, y)匹配现有的字典键,除非您在 Pair 类中覆盖了 EqualsGetHashCode。默认行为是使用引用比较来确定相等性,new anything 不会引用匹配其他内容。请显示Pair 类代码以获得实际答案的帮助。
  • 您的Pair&lt;X,Y&gt; 不足以满足您的用例。在没有实现GetHashCodeEquals 的情况下,Rufus L 所描述的正是正在发生的事情。同样,我建议使用值元组 (int,int)(即 ValueTuple&lt;int,int&gt;not Tuple&lt;int,int&gt;)作为您的键。它正确地实现了这些方法(要求 in 元组中的类型也正确地实现它,当然,int 确实如此)。

标签: java c# null nullreferenceexception


【解决方案1】:

好的,解决了。 正如你所说,问题是 Pair 类。 我用 ValueTuple 类替换它,现在一切正常,仍然感谢。

【讨论】:

    猜你喜欢
    • 2016-07-10
    • 2016-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-31
    • 1970-01-01
    • 2012-08-01
    相关资源
    最近更新 更多