Make it simpler, you can use read-only properties:
public class User
{
public string FirstName { get; }
public string Surname { get; }
public string Email { get; }
public User(string firstName, string surname, string email)
{
FirstName = firstName;
Surname = surname;
Email = email;
}
}
Now let's consider to make it closed, I do not see any extension point then if you don't have any other requirement against this you should also mark it as not inheritable:
public sealed class User
What next? Make it safer. Your class and its ctor are public then you should validate parameters:
public User(string firstName, string surname, string email)
{
if (firstName == null)
throw new ArgumentNullException(nameof(firstName));
if (surname == null)
throw new ArgumentNullException(nameof(surname));
if (email == null)
throw new ArgumentNullException(nameof(email));
FirstName = firstName;
Surname = surname;
Email = email;
}
If you're using C#7 then consider to use throw exceptions (see pgerchev's comment and t3schb0t's answer).
Class has not to be public? Remove public
from its declaration. Constructor is not intended to be called outside your own assembly but class has to be public? Mark ctor as internal
and assert about its arguments.
Note about Debug.Assert
: obviously this does not mean you won't need to validate somewhere these arguments (see also comments) when building in release mode, just that here you assume they're right. See also Exception Vs Assertion, consider pre/post-conditions not an alternative to validation but - sort of - run-time unit testing:
internal User(string firstName, string surname, string email)
{
Debug.Assert(firstName != null);
Debug.Assert(surname != null);
Debug.Assert(email != null);
FirstName = firstName;
Surname = surname;
Email = email;
}
Do you need any other validation (email
has not to be empty and it has to be a valid e-mail address, for example)? Add them all there. Be careful with people's name validation (see David's linked post).
Anything else? Make it easier to debug:
[DebuggerDisplay("{FirstName} {Surname} ({Email})")]
public sealed class User
Last note: yes, there is an [ImmutableObject]
attribute you may use to decorate your class but AFAIK it's used only by PropertyGrid
control. You may add it as reminder (for you or for future readers) that class has to be immutable but nothing else.
User
class, but it's with regard to any immutable class at all. \$\endgroup\$class User(string FirstName, string Surname, string Email)
. \$\endgroup\$