在C#中使用未初始化的变量

时间:2011-10-28 06:19:57

标签: c# variables

这可能是一个非常简单的问题,但是,我无法弄清楚如何解决这个问题。基本上,我的类Client需要工作地址值,但是,创建客户端时不需要100%。在创建用于对象创建的变量时,我使用的是字符串值,然后从文本框中获取值。然后我检查文本框是否为空,如果是,则变量的字符串值只是一个空格。否则,它是文本框值。

string homeAdd;
if(homeAddressText.Text == String.Empty)
{
    homeAdd = " ";
}
else if (homeAddressText.Text != String.Empty)
{
    homeAdd = homeAddressText.Text;
}

如此处所见..

但是,当我使用此变量创建客户端对象时,我收到错误消息“使用未分配的局部变量'homeAdd'。

Client client = new Client(firstN, lastN, homeAdd, workAdd, email, homeP, cellP);

有一种简单的方法可以进行我需要的检查并仍然使用变量吗?

先谢谢你们的朋友们。

10 个答案:

答案 0 :(得分:4)

将整个else if行更改为:

else

这两个条件完全相反。如果仅在UI线程上触及文本框,那么理论上您的代码将起作用(但是很冗长)。但是,编译器无法确认这一点。

答案 1 :(得分:3)

在这种情况下你应该做的第一件事是解决为什么编译器抱怨。很明显,它认为有一些方法可以执行这两个任务的。现在有时这是因为编译器是“愚蠢的”(或者更确切地说,因为当你涵盖所有可能的情况时,语言设计不够强大,无法注意到)。但是,通常是因为你忽略了某些东西,或者做出了编译器不愿意做出的假设。

您已假设homeAddressText.Text的值在两个调用(不一定有效) !=和{{}之间保持不变当给出相同的操作数时,这将给出反向答案(这是一个更合理的假设,但编译器不会做出一个)。实际上,编译器甚至尝试在这里都不聪明 - 它只是分别考虑每个条件,所以即使这样也不能编译:

==

最终,让你编写冗余代码使语言变得更加复杂是不值得的 - 它会更好来强制你删除冗余。

那么,我们怎样才能避免这种情况呢?我们怎样才能让编制者和任何未来的读者清楚地知道我们肯定会选择一门课程?我们可以简单地删除第二个选项的条件:

// Local variable - can't possibly change...
int x = ...;
int y;
if (x == 5)
{
    y = 1;
}
else if (x != 5) // The compiler *could* realize this is the inverse...
{
    y = 2;
}
Console.WriteLine(y);

现在我们显然将第一个分支作为第二个分支,因为这是if (homeAddressText.Text == String.Empty) { homeAdd = " "; } else { homeAdd = homeAddressText.Text; } 块的整个点。但是,现在我们有了一个模式:

else

个人我喜欢在这种情况下使用条件运算符 - 它的目标是“我想根据条件为变量赋值”更明确:

if (condition)
{
    variable = expression1;
}
else
{
    variable = expression2;
}

因此,在这种情况下,它会将您的代码保留为:

variable = condition ? expression1 : expression2;

现在我可能会离开它 - 但如果我们只提到homeAdd = homeAddressText.Text == String.Empty ? " " : homeAddressText.Text; 一次,它就会很好。如果您发现自己经常这样做,您可能需要考虑编写扩展方法:

homeAddressText.Text

然后你的任务变为:

public static string DefaultIfNullOrEmpty(this string input, string defaultValue)
{
    return string.IsNullOrEmpty(input) ? defaultValue : input;
}

对于使用默认值的情况非常明确(例如,如果你只有空格,默认)但是如果简洁对你来说更重要,你可以重命名:

homeAdd = homeAddress.Text.DefaultIfNullOrEmpty(" ");

答案 2 :(得分:2)

如果我正确理解你的问题,这应该可以做到。

string homeAdd = " "; //initialize to the default value
if(!String.IsNullOrEmpty(homeAddressText.Text))
{
   homeAdd = homeAddressText.Text;
}

答案 3 :(得分:1)

只需更改为:

string homeAdd;
if(homeAddressText.Text == String.Empty)
{
    homeAdd = " ";
}
else
{
    homeAdd = homeAddressText.Text;
}

你不需要第二个,如果你知道它是真的,如果它到达那里。 编译器非常聪明,如果在每个if和else子句中分配了变量,就会初始化变量,但是不够聪明,知道第二个if总是为真(在你的情况下)。

答案 4 :(得分:1)

使用它可以使每件事变得简单而简短。但有点胖:)

string homeAdd = homeAddressText.Text == String.Empty ?  " " :  homeAddressText.Text;

答案 5 :(得分:0)

这样做的简单方法是:

string homeAdd = string.IsNullOrEmpty(homeAddressText.Text) ? " " : homeAddressText.Text;

初始化homeAdd

答案 6 :(得分:0)

删除第二个if条件。

即使您的条件是互斥的,编译器看起来也不会那么远。而且,多线程问题在理论上可能导致homeAddressText.Value的价值发生变化。因此,编译器(正确地)假设两个条件都有可能返回false,在这种情况下homeAdd确实没有初始化。

答案 7 :(得分:0)

string homeAdd = " ";
if (homeAddress.Text != String.Empty) {
    homeAdd = homeAddress.Text;
}

答案 8 :(得分:0)

您可以尝试这样:

   string homeAdd = String.Empty;
    if (homeAddressText.Text != String.Empty)
    {
        homeAdd = homeAddressText.Text;
    }

答案 9 :(得分:0)

在你的代码中,如果你使用别的,否则你的问题就会解决。

我在这里发布一个演示代码,如果我遇到这种问题,我将会这样做。

using System;

namespace MyCompany
{
    internal class Client
    {
        // Class fields and properties.
        private string firstName;
        public string FirstName
        {
            get { return firstName; }
            set { SetStringValue(ref firstName, value); }
        }

        private string lastName;
        public string LastName
        {
            get { return lastName; }
            set { SetStringValue(ref lastName, value); }
        }

        private string homeAddress;
        public string HomeAddress
        {
            get { return homeAddress; }
            set
            {
                if (!string.IsNullOrEmpty(value))
                {
                    homeAddress = value;
                }
                else
                {
                    homeAddress = "No home address";
                }
            }
        }

        private string workAddress;
        public string WorkAddress
        {
            get { return workAddress; }
            set { SetStringValue(ref workAddress, value); }
        }

        private string email;
        public string Email
        {
            get { return email; }
            set { SetStringValue(ref email, value); }
        }

        private long homePhone;
        public long HomePhone
        {
            get { return homePhone; }
            set { SetLongValue(ref homePhone, value); }
        }

        private long cellPhone;
        public long CellPhone
        {
            get { return cellPhone; }
            set { SetLongValue(ref cellPhone, value); }
        }

        // Constructors.
        public Client(string firstName, string lastName, string homeAddress, string workAddress,
            string email, long homePhone, long cellPhone)
        {
            this.FirstName = firstName;
            this.LastName = lastName;
            this.HomeAddress = homeAddress;
            this.WorkAddress = workAddress;
            this.Email = email;
            this.HomePhone = homePhone;
            this.CellPhone = cellPhone;
        }

        // Supporting methods for initialization.
        private void SetStringValue(ref string field, string value)
        {
            if (!string.IsNullOrEmpty(value))
            {
                field = value;
            }
            else
            {
                throw new NullReferenceException();
            }
        }

        private void SetLongValue(ref long field, long value)
        {
            if (value != 0)
            {
                field = value;
            }
            else
            {
                throw new NotSupportedException();
            }
        }
    }

    internal class ClientDemo
    {
        static void Main(string[] args)
        {
            // Inputs.
            Console.Write("Enter your first name: ");
            string firstName = Console.ReadLine();

            Console.Write("Enter your last name: ");
            string lastName = Console.ReadLine();

            Console.Write("Enter your home address: ");
            string homeAddress = Console.ReadLine();

            Console.Write("Enter your work address: ");
            string workAddress = Console.ReadLine();

            Console.Write("Enter your email: ");
            string email = Console.ReadLine();

            Console.Write("Enter your home phone: ");
            long homePhone = long.Parse(Console.ReadLine());

            Console.Write("Enter your cell phone: ");
            long cellPhone = long.Parse(Console.ReadLine());

            // Create client object, assuming that without home address all the fields have data.
            Client myClient = null;
            try
            {
                myClient = new Client
                    (firstName, lastName, homeAddress, workAddress, email, homePhone, cellPhone);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            // Show result.
            Console.WriteLine();

            if (myClient != null)
            {
                Console.WriteLine(myClient.FirstName);
                Console.WriteLine(myClient.LastName);
                Console.WriteLine(myClient.HomeAddress);
                Console.WriteLine(myClient.WorkAddress);
                Console.WriteLine(myClient.Email);
                Console.WriteLine(myClient.HomePhone);
                Console.WriteLine(myClient.CellPhone);
            }

            Console.WriteLine();
            Console.ReadKey(true);
        }
    }
}

希望这会对你有所帮助。 感谢。