更改实例变量的默认值

时间:2014-07-05 12:02:16

标签: c# object instance-variables

假设我有这些代码(并且这些类在同一名称空间中):

 class Animal
 {
    int numberOfLegs = 4; // initialized
    public int returnNumberOfLegs()
    {
      return numberOfLegs;
    }
 }

class Snake
{
   internal Animal myAnimalObject = new Animal();
   myAnimalObject.numberOfLegs = 0; // why is this line not allowed? 
}

class Program
{
   public static void Main(string [] args)
   {
      Snake mySnakeObject = new Snake();
      Console.WriteLine("Snake");
      Console.WriteLine("Number of Legs: {0}", mySnakeObject.myAnimalObject.returnNumberOfLegs());
   }
}

观察班级Snake。当我在Main()中放置这两行代码时,如果我使用正确的访问修饰符声明变量numberOfLegs,则可以/允许它。为什么我不能在班级本身中做到这一点?我应该怎么做才能允许它?

请注意,类Snake中的第二行代码无效,这些是它产生的错误: 1)错误1无效令牌' ='在类,结构或接口成员声明中 2)错误2' myNamespaceName.Snake.myAnimalObject'是一个'字段'但是像''类型'

感谢。我只是想了解这一点。

编辑: 好的,谢谢你们。我知道施工人员和继承人,但不知何故,我被迫做了这件事,而且他们很难做到并且不那么聪明。"方式,用于学习目的(?)。而且我甚至不得不将默认值设置为4.感谢您的回复。另外,我刚刚编写了这些课程。

4 个答案:

答案 0 :(得分:3)

因为可执行代码应放在构造函数中或某些方法/属性中。 你不能将代码放在类中,把它放在构造函数中。

    class Snake
    {
        internal Animal myAnimalObject = new Animal();
        public Snake()
        {
              myAnimalObject.numberOfLegs = 0;
        }
    }

写作时

    internal Animal myAnimalObject = new Animal();

在类体中,它是一种语法糖;编译器将创建构造函数并将代码行放入其中。 它看起来像

    class Snake
    {
        internal Animal myAnimalObject;
        public Snake()
        {
              myAnimalObject = new Animal();
              myAnimalObject.numberOfLegs = 0;
        }
    }

答案 1 :(得分:1)

首先,您无法在类初始化程序中执行此操作:

myAnimalObject.numberOfLegs = 0;

由于您不是自己设置类成员,而是与类成员进行交互,因此您必须在构造函数中执行此操作:

public Snake()
{
    myAnimalObject.numberOfLegs = 0;
}

另外,要访问numberOfLegs,需要internalpublic

internal int numberOfLegs = 4; // initialized

然而,更重要的是整个场景,这似乎是一个非常奇怪的抽象。虽然我的一部分赞成使用组合而不是继承,但这似乎更像是一种保证继承的情况。似乎Animal默认情况下不应初始化numberOfLegs的任何值。实际上,鉴于现实世界的概念被建模,Animal甚至不应该是一个具体的对象。相反,我可能尝试类似的事情:

abstract class Animal
{
    public abstract int NumberOfLegs { get; }
}

class Snake : Animal
{
    public override int NumberOfLegs { get { return 0; } }
}

Snake Animal的想法是,Animal本身不能存在,除非它是特定的类型 Animal,每个单独类型的Animal在内部控制自己的值,所有抽象Animal类都定义了这些值需要的是什么

答案 2 :(得分:0)

您应该使用继承。使动物成为一个抽象类,所有动物的基类。在这种情况下,构图(你现在使用的)没有多大意义。

abstract class Animal
{
    protected int numberOfLegs = 4; // default number of legs
    public int NumberOfLegs { get { return numberOfLegs; } }

    public Animal(int legs)
    {
        numberOfLegs = legs; // initialize number of legs
    }
}

然后所有的具体动物都来自这个类。

class Snake : Animal
{   
   public Snake() : base(0) // specify that number of legs is 0
   {

   }
}

base(0)是对基类构造函数的调用,因此您使用参数0调用Animal(int legs)

答案 3 :(得分:0)

这样做:

abstract class Animal
{
    private readonly int numberOfLegs; 

    protected Animal(int nrLegs = 4)
    {
       numberOfLegs = nrLegs;
    }
    public int returnNumberOfLegs()
    {
      return numberOfLegs;
    }
}

class Snake : Animal
{
   public Snake() : base(0)
   {
   }
}