简体   繁体   English

C#不会让我在方法的开头放置某些变量。我不明白为什么不

[英]C# won't let me put certain variables at the beginning of method. I don't understand why not

I've been learning C# for a little over a month. 我已经学习了一个多月的C#。 I am working on an exercise where I ask the user to enter a time in a 24-hour clock format and check if it's valid. 我正在进行一项练习,我要求用户以24小时时钟格式输入时间并检查它是否有效。

That's not important though. 但这并不重要。 My problem is I'm confused about an error. 我的问题是我对错误感到困惑。 The below code creates an unhandled exception, and says my input string was not in a correct format. 下面的代码创建了一个未处理的异常,并说我的输入字符串格式不正确。 It specifies line 22. (The hour variable.) 它指定第22行。(小时变量。)

Now, I've already fixed it, by moving all the variables except userInput inside the try block. 现在,我已经通过在try块中移动除userInput之外的所有变量来修复它。 But I'm confused why that fixed it. 但我很困惑, 为什么修复它。 I'm very new, and have tried googling, but honestly don't really know how to even phrase my question. 我很新,并尝试使用谷歌搜索,但说实话,我真的不知道如何甚至说出我的问题。

The complete (pre-fixed) code is below. 完整(预先修复)的代码如下。 I appreciate everyone's patience. 我感谢大家的耐心。

{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Please enter a time value in the 24-hour time format. (ex. 19:00)");
            var userInput = Console.ReadLine();
            var userComponents = userInput.Split(':');
            var hour = Convert.ToInt32(userComponents[0]);
            var minute = Convert.ToInt32(userComponents[1]);    

            if (String.IsNullOrWhiteSpace(userInput))
            {
                Console.WriteLine("Invalid Time");
                return;
            }

            try
            {                      
                if (hour <= 23 && hour >= 00 && minute >= 0 && minute <= 59)
                    Console.WriteLine("Ok");
                else
                    Console.WriteLine("Invalid Time");
            }

            catch(Exception)
            {
                Console.WriteLine("Invalid Time");
            }
       }
    }
}

Someone requested I post the fixed code: 有人要求我发布固定代码:

{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Please enter a time value in the 24-hour time format. (ex. 19:00)");
            var userInput = Console.ReadLine();  

            if (String.IsNullOrWhiteSpace(userInput))
            {
                Console.WriteLine("Invalid Time");
                return;
            }

            try
            {
                var userComponents = userInput.Split(':');
                var hour = Convert.ToInt32(userComponents[0]);
                var minute = Convert.ToInt32(userComponents[1]);

                if (hour <= 23 && hour >= 00 && minute >= 0 && minute <= 59)
                    Console.WriteLine("Ok");
                else
                    Console.WriteLine("Invalid Time");
            }

            catch(Exception)
            {
                Console.WriteLine("Invalid Time");
            }
       }
    }
}

Someone also requested the debugger info: 有人还要求调试器信息:

System.IndexOutOfRangeException HResult=0x80131508 Message=Index was outside the bounds of the array. System.IndexOutOfRangeException HResult = 0x80131508 Message = Index超出了数组的范围。 Source=Section 6 24 Hour Time 来源=第6节24小时时间
StackTrace: at Section_6_24_Hour_Time.Program.Main(String[] args) in D:\\Repos\\Mosh C# Udemy\\Exercises\\C# Fundamental Exercises\\Section 6 24 Hour Time\\Section 6 24 Hour Time\\Program.cs:line 23 StackTrace:在D:\\ Repos \\ Mosh C中的Section_6_24_Hour_Time.Program.Main(String [] args)#Udemy \\ Exercises \\ C#基础练习\\第6节24小时时间\\第6节24小时时间\\ Program.cs:第23行

As said in the comments, you're running str.split() and then just accessing the output of it with index 0 and index 1 . 如评论中所述,您正在运行str.split() ,然后只使用索引0和索引1访问它的输出。 Upon requesting index 0 or 1 whilst it's not there you'll get an Index out of range exception telling you Item on index 0 or 1 is not there. 在请求索引01而它不存在时,您将获得索引超出范围异常,告诉您索引0或1上的项目不存在。

Then there's the issue with Convert.ToInt32 as you don't catch an overflowexception or formatexception . 然后是Convert.ToInt32的问题,因为你没有捕获overflowexceptionformatexception

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Please enter a time value in the 24-hour time format. (ex. 19:00)");
        var userInput = Console.ReadLine();
        if(string.IsNullOrEmpty(userInput)) {
            Console.WriteLine("No input");
            return;
        }

        if(!userInput.Contains(':')) {
            Console.WriteLine("Input does not have `:` in it. Invalid Time.");
            return;
        }

        var userComponents = userInput.Split(':');
        if(userComponents.Length != 2) { 
            Console.WriteLine("Invalid Time");
            return;
        }
        if(string.IsNullOrEmpty(userComponents[0]) || string.IsNullOrEmpty(userComponents[1]) {
            Console.WriteLine("No hours or minutes given. Invalid Time");
            return;
        }
        try {
            var hour = Convert.ToInt32(userComponents[0]);
            var minute = Convert.ToInt32(userComponents[1]);    
        } catch(OverFlowException e) {
            // Do something with this.
            return;
        } catch (FormatException e) {
            // Do something with this.
            return;
        }

        if (hour <= 23 && hour >= 00 && minute >= 0 && minute <= 59)
            Console.WriteLine("Ok");
        else
            Console.WriteLine("Invalid Time");

   }
}

Edit 编辑

As mentioned by @ckuri and What's the main difference between int.Parse() and Convert.ToInt32 one should prefer int.TryParse() over Convert.ToInt32 since we're dealing with user input here. 正如@ckuri所提到的那样int.Parse()和Convert.ToInt32之间的主要区别是什么,因为我们在这里处理用户输入,所以应该int.TryParse()Convert.ToInt32 int.TryParse()

  • If you've got a string, and you expect it to always be an integer (say, if some web service is handing you an integer in string format), you'd use Int32.Parse() . 如果你有一个字符串,并且你希望它总是一个整数(比如说,如果某个Web服务正在以字符串格式处理一个整数),你将使用Int32.Parse()

  • If you're collecting input from a user, you'd generally use Int32.TryParse() , since it allows you more fine-grained control over the situation when the user enters invalid input. 如果您正在收集用户的输入,则通常使用Int32.TryParse() ,因为它允许您在用户输入无效输入时对情况进行更细粒度的控制。

  • Convert.ToInt32() takes an object as its argument. Convert.ToInt32()接受一个对象作为其参数。 (See Chris S's answer for how it works) (参见Chris S的答案,了解它的工作原理)

Convert.ToInt32() also does not throw ArgumentNullException when its argument is null the way Int32.Parse() does. Convert.ToInt32()在其参数为Int32.Parse()的方式为null时也不会抛出ArgumentNullException That also means that Convert.ToInt32() is probably a wee bit slower than Int32.Parse() , though in practice, unless you're doing a very large number of iterations in a loop, you'll never notice it. 这也意味着Convert.ToInt32()可能比Int32.Parse()慢一点,但在实践中,除非你在循环中进行大量的迭代,否则你永远不会注意到它。

Before you access the elements of the array, check if it has the desired length: 在访问数组的元素之前,请检查它是否具有所需的长度:

if (userComponents.Length < 2)
{
    Console.WriteLine("Invalid Time");
    return;
}

var hour = Convert.ToInt32(userComponents[0]);
var minute = Convert.ToInt32(userComponents[1]);

Note that the input string may not contain the colon, so Split will return an array with only one element. 请注意,输入字符串可能不包含冒号,因此Split将返回仅包含一个元素的数组。 In such case userComponents[1] does not exist, hence the exception. 在这种情况下, userComponents[1]不存在,因此是例外。

This error indicates that you are trying to convert a string value to int (in this case) that is not castable. 此错误表示您正在尝试将字符串值转换为不可转换的int(在本例中)。 So you should make sure that the value you input after splitting is castable to int, also it is nice to Trim() them before casting: 因此,您应该确保在拆分后输入的值可以转换为int,在转换之前修剪它们也很好:

 var hour = Convert.ToInt32(userComponents[0].Trim());
 var minute = Convert.ToInt32(userComponents[1].Trim()); 

在尝试拆分userInput之前,首先应检查IsNullOrWhiteSpace

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

相关问题 CMD、C# & Java 不允许我使用在同一行设置的环境变量 - CMD, C# & Java won't let me use environment variables set on the same line 为什么不让我通过此列表? - Why won't it let me pass this list? 单元测试不会“覆盖”简单的get方法。 (C#) - Unit test won't “cover” simple get method. (c#) RuntimeBinderException - C#.NET 4动态关键字 - 帮助我理解为什么方法不匹配 - RuntimeBinderException - C# .NET 4 Dynamic Keyword - Help Me Understand Why Method Isn't Matching (C#“ Random”是一个命名空间,但像一个变量一样使用)我不明白为什么 - (C# 'Random' is a namespace but is used like a variable) I don't understand why 我不明白这个短语是如何用c#计算的 - I don't understand how this phrase is calculated in c# fluentassertions C# 我不明白 Should().NotBeNull() - fluentassertions C# I Don't understand Should().NotBeNull() 我不明白在C#中使用“while(true)”和“for(;;)”循环! - I don't understand the use of “while(true)” and “for(; ;)” loops in C#! 我真的不明白C#的参考 - I really don't understand the reference of C# 程序不会让我以任何方式清除我的 listBox [C#, WinForms] - Program won't let me clear my listBox in any way [C#, WinForms]
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM