简体   繁体   English

C#对象引用未设置为对象?

[英]C# Object reference not set to an object?

在此输入图像描述

public static void duel(String user, String user1, String user2)
        {
            int[] value = null;
            String winner;
            for (int i = 0; i < 2; i++)
            {
                Random rand = new Random((int)DateTime.Now.Ticks);
                int numIterations = 0;
                numIterations = rand.Next(2, 12);
                value[i] = numIterations;//This is line 286
            }
            if (value[0] > value[1])
            {
                winner = user1;
            }
            else
            {
                winner = user2;
            }
            Console.WriteLine(user + " Started a duel against " + user1 + " and " + user2 + "!");
            Console.WriteLine(user1 + " rolled " + value[0] + " and " + user2 + " rolled " + value[1] + "!");
            Console.WriteLine(winner + " is the winner!");
        }

What exactly is wrong here? 这到底出了什么问题? When I set int[] value = null it compiles but if I remove the null it says Use of unassigned local variable 'value' Line 286 当我设置int[] value = null它会编译,但如果我删除null,则表示Use of unassigned local variable 'value' Line 286

Well yes, you have to assign a value to the value variable before you use it - but when you've set it to null, you will get a NullReferenceException when you try to use it. 是的,你必须在使用之前为value变量赋值 - 但是当你将它设置为null时,当你尝试使用它时得到NullReferenceException It looks like you want a two element array, so use 看起来你想要一个双元素数组,所以使用

int[] value = new int[2];

However, with the code you've written you'll almost certainly end up with the two values being the same, as you're creating two instances of Random at almost exactly the same time . 但是,使用您编写的代码,您几乎肯定最终会得到两个值相同,因为您几乎在同一时间创建了两个Random实例。 See my article on Random for more information. 有关更多信息,请参阅我Random文章

I would pass a Random instance into the method, and rewrite it like this - without the somewhat-pointless loop: 我会将一个Random实例传递给方法,并像这样重写它 - 没有一点点无意义的循环:

public static void Duel(Random rng, String user, String user1, String user2)
{
    // Using Next(2, 12) doesn't really mimic 2 dice of 1-6; it actually mimics
    // a single 10-sided die with values 2 to 11 inclusive.
    int score1 = rng.Next(1, 7) + rng.Next(1, 7);
    int score2 = rng.Next(1, 7) + rng.Next(1, 7);

    // Note: this is biased in favour of user2 in case of equality
    string winner = score1 > score2 ? user1 : user2;

    Console.WriteLine("{0} started a duel between {0} and {1}!",
                      user, user1, user2);
    Console.WriteLine("{0} rolled {1} and {2} rolled {3}!", user1, score1,
                      user2, score2);
    Console.WriteLine("{0} is the winner!", winner);
}

Things to note here: 这里要注意的事项:

  • Our method depends on something which it can't necessarily create correctly itself (the Random ) so that is injected. 我们的方法取决于它本身不能正确创建的东西( Random ),因此注入。
  • Simulate rolling two dice (which is what I assume the aim is) by rolling two single dice, not picking a single number in the range [2, 12] uniformly. 通过滚动两个单个骰子来模拟滚动两个骰子(这是我假设的目标),而不是均匀地在[2, 12]范围内选择单个数字。
  • The second parameter to Random.Next is an exclusive upper bound (I got that wrong until I was checking it over) Random.Next的第二个参数是一个独占上限(在我检查之前我弄错了)
  • Use of the conditional operator when you want to pick one expression or another based on a condition, and do the same thing with the result either way 当您想根据条件选择一个或另一个表达式时使用条件运算符 ,并以任一方式对结果执行相同的操作
  • Use of composite format strings to make it easier to format strings than simple concatenation 使用复合格式字符串可以比简单串联更容易格式化字符串
  • Following .NET naming conventions ( Duel , not duel ) 遵循.NET命名约定( Duel ,不是duel

Change the line to: 将行更改为:

int[] value = new int[2];

You need to create an empty array so that you can use it later. 您需要创建一个空数组,以便以后可以使用它。

If you don't set it to anything you get the Use of unassigned local variable , because you've declared the variable, but haven't given it a value. 如果你没有将它设置为任何你得到的Use of unassigned local variable ,因为你已经声明了变量,但没有给它一个值。

If you set it to null then that's giving it a value, but you're also not putting anything in that variable. 如果你将它设置为null然后给它一个值,但你也没有在该变量中放置任何东西。 Your code further down expects to be able to use elements 0 and 1, however although you declared that value is an array you've not created an array to put into the variable, so you get the error when trying to access the elements of a non-existent array. 你的代码进一步向下期望能够使用元素0和1,但是虽然你声明该value是一个数组你没有创建一个数组放入变量,所以你在尝试访问元素时得到错误不存在的数组。

The code above fixes this by setting the variable to an array with 2 element, which would contain the default for the type in the array ( int ), which in this case would be 0 until you set them equal to something. 上面的代码通过将变量设置为具有2个元素的数组来修复此问题,该元素将包含数组( int )中类型的默认值,在这种情况下,它将为0直到您将它们设置为等于某个值。


Bad analogy time: 比喻时间不好:

Imagine i'm planning on putting a bookshelf in my bedroom. 想象一下,我打算在我的卧室里放一个书架。 I make space for it (declare the variable), but i don't put a bookshelf in that space (set the variable it to null, or don't set it at all). 我为它创建了空间(声明变量),但我没有在该空间中放置书架(将变量设置为null,或者根本不设置它)。

If i go to get something on the 2nd shelf i'm obviously going to have a problem as although i've made space (a variable) in my room (my program) i've not put a bookshelf there (declared an array to go in the variable). 如果我去第二个货架上拿东西我显然会遇到问题,因为虽然我已经在我的房间(我的程序)中制作了空间(一个变量)但我没有把书架放在那里(声明一个阵列到进入变量)。


For more info, see the Arrays Tutorial on MSDN . 有关详细信息,请参阅MSDN上Arrays教程

You are referencing value[i], but you haven't actually intialized value[] yet. 您正在引用值[i],但您实际上还没有初始化值[]。 You need to do something like 你需要做点什么

value = new int[2];

You haven't assigned your int[] an instance. 您尚未为int[]分配实例。 If you know there will always be 2 values, you can use: 如果您知道总有2个值,您可以使用:

int[] value = new int[2];

If you don't know that you'll only ever have 2 values, consider using a List: 如果您不知道您只有2个值,请考虑使用List:

List<int> value = new List<int>();

In c# you need to initialize your variables to some value or it will not compile. 在c#中,您需要将变量初始化为某个值,否则将无法编译。 To fix your runtime error, you need to initialize value into an array (instead of null). 要修复运行时错误,需要将值初始化为数组(而不是null)。 Since you are looping through value twice I assume you need to do something like this: 由于你循环遍历值两次,我认为你需要做这样的事情:

int[] value = new int[2];

你需要在某处创建你的数组:

int[] value = new int[2];

如果您只是在开头声明数组,那么您应该是安全的。

int[] value = new int[2];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM