构造函数混淆 - '从未分配给,并且将始终具有其默认值'

时间:2014-02-11 12:46:42

标签: c# .net constructor attributes initialization

这些是我的指示:

iii)给Pair一个构造函数  iv)为钥匙提供一套固定的财产  v)还提供key的get属性。

在检查了我可以在此论坛上找到的尽可能多的构造函数线程之后,我发现虽然给出的答案非常准确和准确,但仍然有一些我不完全理解的东西。

我们被告知,如果完全定义了构造函数,那么必须初始化所有属性,以及禁止结构中的属性初始化。

我的代码:

 using System ;
   using System.Drawing ; 
   // above namespace 
   // has the class Color 

   public class PairApp
   {
      public static void Main()
      {
            Pair two = new Pair();
            two.print(); 
      }

      struct Pair
      {

                int key;
                Color colour;


                public void print()
                {
                    Console.WriteLine("key : " + key );
                    Console.WriteLine("colour : " + colour);
                }
      }
   }
   //
   // Some values from the 
   // class Color
   //    Color.Red
   //    Color.Cyan
   //    Color.DarkGray
   //

我的问题:

  1. 为什么我需要为Pair创建构造函数?这不是Pair two = new Pair();的作用吗?

  2. 如果Pair two = new Pair();是构造函数,那么已经定义了,对吧?如果已定义,我将如何得不到下面列出的错误。

  3. 当他说“结构中属性的零碎初始化被禁止”时,我的讲师意味着什么?我经常讨论编程世界中使用的术语,所以帮助我:)

  4. 调试:

    airapp.cs(17,16): warning CS0649: Field `PairApp.Pair.key' is never assigned to, and will always have its default value `0'
    pairapp.cs(18,18): warning CS0649: Field `PairApp.Pair.colour' is never assigned to, and will always have its default value
    Compilation succeeded - 2 warning(s)
    

    EDIT 更新的代码:

    现在它运行时没有任何错误。非常感谢大家解释得这么好!

    但是,它提出了以下错误:pairapp.cs(14,14): error CS1520: Class, struct, or interface method must have a return type。在查找之后,我看不出它与http://msdn.microsoft.com/en-us/library/aa288208(v=vs.71).aspx

    中显示的示例有什么不同

    我想要完成的任务(希望我没有设法让自己迷惑)是创建一个构造函数,将值分配给结构的字段。 我这样做了吗?

    我还删除了以下部分,因为在添加了下面更新版本中可以看到的内容之后感觉多余。

    Pair two;
    
            two = new Pair();
            two.print();
    

    我的更新代码:

    using System ;
       using System.Drawing ; 
       // above namespace 
       // has the class Color 
    
       public class PairApp
       {
          public static void Main()
          {
    
                Lion p1 = new Lion(5, Color.Red);
                p1.print(); 
          }
          public Lion(int key, Color colour)
          {
                this.key = key;
                this.colour = colour;
          } 
          struct Pair
          {
    
                    int key;
                    Color colour;
    
    
                    public void print()
                    {
                        Console.WriteLine("key : " + key );
                        Console.WriteLine("colour : " + colour);
                    }
          }
       }
       //
       // Some values from the 
       // class Color
       //    Color.Red
       //    Color.Cyan
       //    Color.DarkGray
       //
    

2 个答案:

答案 0 :(得分:2)

  1. 你没有需要为Pair创建一个构造函数,因为它可以正常使用它的默认构造函数(你已经列出的例子)。但是如果你的struct有应该使用某些值初始化的字段,那么最好立即创建一个构造函数来获取这些值并构造你的结构。默认构造函数不会使用除默认值之外的任何内容为您初始化字段(如错误输出中所示)。

    这将我们带到您的下一个问题......

  2. 类型实际上可以有一个或更多构造函数。您列出的是默认构造函数,如果您不编写任何自己的参数并且不接受任何参数,则会自动创建,除了允许在内存中创建结构的实例之外什么都不做。

    在您的情况下,您需要创建一个带有两个参数keycolour的构造函数,并将它们分配给结构中的字段。签名应该看起来像public Pair(int key, Color colour),您需要将字段this.keythis.colour分配给构造函数中的参数。

  3. 在这种情况下,零碎的初始化可能仅仅是指初始化一些字段而不是所有字段(该字不具有我所知道的任何特定于编程的含义)。

    您看到的警告正是在代码中保留未初始化或未分配某些字段的结果。另一个例子,如果您创建的构造函数只为key分配了值,但从未分配给colour,那么输出会是什么?


  4. 构造函数有两个问题:

    1. 它必须与它正在构建的类型相同。所以在这种情况下,它是Pair。 (原来在我的答案中有一个拼写错误,可能误导了你,我现在已经修好了。)

    2. 它需要在里面出现结构定义,而不是在它旁边。 (换句话说,除了结构本身的字段和方法之外。)

答案 1 :(得分:0)

Pair two = new Pair();

不是构造函数,它将Pair的实例分配给局部变量。实例是使用构造函数创建的,但这里没有定义。

构造函数是在类中定义的东西。它看起来像一个没有返回值的方法,可以覆盖参数(以减轻你的生活)。

struct Pair
{
    public Pair() {} // constructor
}

这听起来不对,或者你重新说明它是错误的:

  

如果完全定义了构造函数,那么必须初始化所有属性,以及禁止结构中的属性初始化

您的问题是access modifiers。默认情况下,您的字段为private(如果我记得在C++结构中右侧默认为公共字段,这可能是混淆的原因)。因为你没有定义任何构造函数 - 使用默认值(它只为所有字段分配内存,但为它们分配任何值)。

结构中的私有字段和构造函数中没有字段初始化(实际上,没有构造函数定义) - 意味着你根本没有为它分配任何东西(你只是使用 print方法中的值)。这使编译器确定,你在某处错了。添加任何类型的设置都会使compiler shut = D

struct Pair
{
    int key;
    Color colour;

    public void print()
    {
        Console.WriteLine("key : " + key );
        Console.WriteLine("colour : " + colour);
    }

    // no more warning, but.. are you sure? 
    public void LOL()
    {
        key = 0;
        Color = Color.Red;
    }
}