简体   繁体   中英

Auto properties is not working in c#

Hello there fellow friends. I have a small problem with auto properties. I'm new to programming in general and I've only started learning about classes and objects. When I try to use auto properties, the field does not get exposed. (not sure if thats the right way of putting it) Take a look at the commented parts of the Properties in both animal Classes to understand what I'm talking about.

Right now I have this Animals Class

public class Animals
{
    //fields
    private string name;

    public Animals(string name)
    {
        this.name = name;
    }

    // default constructor
    public Animals()
    { }

    //This is the problematic portion
    public string Name { get; set; }


    public void Bark()
    {
        Console.WriteLine("{0} said WoWOW", name);
    }

}

This is my main program class

class Program
{
    static void Main(string[] args)
    {

        Console.WriteLine("Enter name: ");
        string name = Console.ReadLine();
        Animals dog = new Animals(name);
        dog.Bark();

        Animals cat = new Animals();
        Console.WriteLine("Enter second name: ");
        cat.Name = Console.ReadLine();
        cat.Bark();


    }
}

The output is as follows. The last Line is my problem

    Enter name:
    bob
    bob said WoWOW
    Enter second name:
    sarah
     said WoWOW //sarah is missing here

However when i change the properties from {get;set} to its full version in the class. It outputs the correct output.

edited code

public class Animals
{
    //fields
    private string name;

    public Animals(string name)
    {
        this.name = name;
    }

    public Animals()
    { }

    //apparently this is the correct way of making properties
    public string Name
    {
        get { return name; }
        set { name = value; }
    }


    public void Bark()
    {
        Console.WriteLine("{0} said WoWOW", name);
    }

}

output: //Sarah is present in the last line

    Enter name:
    bob
    bob said WoWOW
    Enter second name:
    sarah
    sarah said WoWOW

My question is: Why is it when auto properties is used I do not get my desired output but when i write the properties in full I do get my desired outcome. Thanks for taking a look at my question. Hopefully it wasn't too long! ;]

This will work:

public class Animals
{
    //fields
    private string name; // <-- You don't need it when you have auto properties

    public Animals(string name)
    {
        Name = name;// <-- Using auto property
    }

    public string Name { get; set; }

    public void Bark()
    {
        Console.WriteLine("{0} said WoWOW", Name);//<-- Using auto property
    }

}

Also, you should take a look at What are Automatic Properties in C# and what is their purpose? and Auto-Implemented Properties (C# Programming Guide)


Side note 1: An empty, parameterless, public constructor is useless if you don't have other constructor. As Joe pointed out, if, in your example, you remove it, you won't be able to call var a = new Animals();

Side note 2: it is more than common to name your classes with a singular noun, here, Animal .

Well, this two members of the class are not really connected.

private string name;

public string Name { get; set; }

What happens here is that you declare field, and auto-property which creates automatically underlying field and works with this second field (not the one you created).

You can either use Auto-Property's getter and setter, or define this methods explicitly (using normal property) :

public string Name { get { return name; } set { name = value; } }

Auto-Property creates field and automatically implements code above for you thus saving your time. If you want to create field and property that works with it by simply setting (or getting) value of this field then auto-properties is a way to go. You can just define auto-property and works with its get; and set; methods. In some cases you may need to add some extra logic (for example you'd like to validate value inside the property before saving it) then the only option is to implement getter and setter methods by yourself :

public string Name 
{ 
   get { return name; }

   // sets field value depending on condition
   set { name = !string.IsNullOrEmpty(value) && value.Length < 20 ? value : name; } 
}

Do not forget that property's getter and setter methods as any other methods use access modifiers. By default these accessors have the same visibility, or access level that of the property however sometimes you may need to encapsulate one of this methods by changing it access modifier to more restricted :

// setter of this property is only accessible inside the class or sub-classes
public string Name { get; protected set; } 

When you use an auto property

public string Name  { get; set; }

the compiler doesn't use "name" as a backing field.
Instead it generates it's own field with unique name:

[CompilerGenerated]
private string <Name>k__BackingField;

Note the < and >, which are not characters you can use in your own field names. You can't access the backing field directly in this case.

In your code you declare the auto-property Name but you never use it. This is what is happening with your code:

这就是你的代码的工作方式

Casing does matter, name refers to the field and Name refers to the property. They are different things in this context.

You don't need to declare fields when using auto-properties, the compiler will create them for you.

You should declare fields when you will use them as private in your class, or when you need a more elaborated property.

So remove the field and change the constructor to:

public Animals(string name)
{
    // property Name receives constructor parameter name
    Name = name;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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