-2

I started writing a Person class for an end of year Project, I found a basic getset property from a previous project, but it has in a UML comment that the method currently has no protection.

Is this is simple as changing "public" to "Protected"? or am I missing something?

//PROPERTIES

    /// <summary>
    /// Property for "Title"
    /// Read & Write property for attribute "Title"
    /// set method currently has no protection
    /// </summary>
    ///
    public string Title
    {
        get { return title; }
        set { title = value; }
    }
    
    public string FirstName
    {
        get { return firstname; }
        set { firstname = value; }
    }
    
    public string MiddleName
    {
        get { return middlename; }
        set { middlename = value; }
    }
    
    public string LastName
    {
        get { return lastname; }
        set { lastname = value; }
    }

PS. I'm in a basic OOP course, it's very simple code (My project only requires ONE property :P), I've never used validation within a get/set before, I'll look into it, but I think:

"protected set {title = value; }"

was exactly what I was looking for.

Community
  • 1
  • 1
  • 5
    That depends on the *definition* of `protection` of the person writing that comment. Does it have protection from *invalid input*, or *invalid use*, or *other*? If they want the `set` method protected from use outside the class, use `protected set`. – Der Kommissar Apr 26 '15 at 19:23
  • Could you post the full class? I think I know what they want you to do but I need to see the full class in order to confirm it. – Jevgeni Geurtsen Apr 26 '15 at 19:25
  • 1
    I've edited in your code in the text of the question and removed the link to your image. You should use text to represent code instead of a screenshot in the future. Thanks! – jdphenix Apr 26 '15 at 19:28
  • 1
    Are you sure protected is what you want, and not `private`? `protected` is intended for classes used for inheritance, and in any case I can think of regarding representing people, composition over inheritance would be better. – jdphenix Apr 26 '15 at 19:38
  • Well, the attributes in Person eventually becomes part of a member, Person has an Address and Details class it inherits from. I'm not a very experienced programmer, but It both inherits and is inherited. – Johnny Mccrum Apr 26 '15 at 19:39
  • _was exactly what I was looking for_ - what benefit do you think it brings? – H H Apr 26 '15 at 19:42
  • I'm hoping that protected will offer more protection so that the attribute cannot be changed as easily. – Johnny Mccrum Apr 26 '15 at 19:43
  • Then why not make it `private` ? – H H Apr 26 '15 at 19:47
  • Wouldn't that make it inaccessible? – Johnny Mccrum Apr 26 '15 at 19:50
  • It would be readonly from outside the class, and that's what 'protection' means. – H H Apr 26 '15 at 20:08

3 Answers3

3

From this

/// set method currently has no protection
public string Title
{
    get { return title; }
    set { title = value; }
}

I would guess that protection is not about the protected access-modifier but about data validation.

Validation can take many different forms, one possible form would look like

public string Title
{
    get { return title; }
    set 
    { 
        if (value == title)  
          return;
        if (string.IsNullOrEmpty(value))
          throw new ArgumentException("Title");
        title = value;  
    }
}
H H
  • 263,252
  • 30
  • 330
  • 514
  • value == title will throw a NullReferenceException if value is null. Equals(value, title) is normally a better property equality pattern. – Holstebroe Apr 26 '15 at 19:37
  • @Holstebroe - no it won't throw, try it. And it isn't better, that `Equals()` is very, very rarely needed but everybody is polluting all their code with it nowadays. And using it all the time makes it lose its signal function. – H H Apr 26 '15 at 19:39
  • You are right. Only if operator == is overloaded, == will throw an exception and not for strings. – Holstebroe Apr 26 '15 at 19:44
  • I think the overuse of equals comes from the Java advice of "how do I compare strings in Java?" – jdphenix Apr 26 '15 at 19:53
  • @jdphenix - and from ReSharper property generators and guidelines. Code generators go for the safest code, not always for the cleanest. But I guess that when you want guidelines that people should blindly follow, Equals() is OK. – H H Apr 26 '15 at 20:06
  • @HenkHolterman - If you are working with e.g. WPF or Entity Framework, there can be a penalty involved if you are assigning a semantically equal value to a property. Here I would argue, that Equals is safer, since overriding Equals is the common practice for implementing semantic comparison. – Holstebroe Apr 26 '15 at 20:45
1

In C# you can have different protection for setters and getters:

public class Person
{
    public string Name { get; protected set; }   
}

This will allow any class to read Name, but only Person or derivatives to write it. Here I am using an auto-property, but a similar construction can be used with backing fields.

Holstebroe
  • 4,993
  • 4
  • 29
  • 45
  • 4
    It is not clear from the question if the OP is referring to literally ` protected` property, or some other concept. – jdphenix Apr 26 '15 at 19:29
  • didn't know you could individually give protection to a get/set, thanks for this! – Johnny Mccrum Apr 26 '15 at 19:30
  • Agreed - should get clarification as to whether or not the comment about protection meant that there was no validation in the setter, or that the setter should be "protected" – Rufus L Apr 26 '15 at 19:30
  • You can indeed have different combined read/write protection. This is the way to go if you want to make your class immutable, which is often a good design choice. Even for mutable classes it is often a good choise to limit who will be allowed to update the properties. – Holstebroe Apr 26 '15 at 19:33
0

You want to protect your class's data from mutation from the outside. In OOP parlance this is known as encapsulation.

Consider this code snippet:

sealed class Person {
    public Person(string name) { 
        this.name = name; 
    }

    public string Name { get; private set; } 
}
  • An instance of Person cannot be mutated from the outside. As it is an instance of Person is immutable.
  • Derived from above, code that uses Person doesn't have to worry about risking editing a Person:

    Person p = new Person('Bob'); p.Name = 'Sally' // won't work, set is not accessible

Other notes:

You probably don't want literally protected. It's use case is when you have a class which is intended for inheritance. If you're representing people in a data model, you don't want to use it.

In your comments, you stated you wanted to derive a class Address from a Person. That is an inappropriate relationship to establish. Consider this plain English sentence.

An address is also a person.

Nonsense, right? What about this one:

A person has an address.

Makes much more sense. More related reading.

So in this sense, you would establish the HAS-A relationship with composition - an address would be a member of a Person.

sealed class Person {
    public Address HomeAddress {get; private set;} 

    //.. and other members
}

The above establishes that again, code outside of a Person instance cannot mutate the address*, and a Person has an Address, which makes sense in this context.

*This is true in the sense that the HomeAddress reference is immutable from the outside, but the Address object it refers to is not. To avoid confusion and FUBAR later, make sure Address is also immutable.

Community
  • 1
  • 1
jdphenix
  • 15,022
  • 3
  • 41
  • 74