I want to validate if the name value entered by the user does not include any numbers and is within the range [3-8] characters. I applied the test in the setter property as it is where the value will be assigned to the private attribute name. The condition is if the name is less than 3 or greater than 8 or it contains any numbers, the set value for the attribute -name- will be "Unnamed". However, after creating an instance of the class and passing the name argument ("Gigi5") to the constructor, instead of returning "Unnamed" (since the name contains a number) it returned "Gigi5" which is not what it's supposed to happen based on the condition. The confusing thing is, when I put the conditional station in the getter property, only then then I get the correct output, which doesn't make sense because it is in the setter where the data is assigned to the attribute and the getter will only retrieve the value that was sat by the setter. right?
Now I tried one thing, The constructor takes arguments which are assigned to the private attributes directly. I tried replacing the [this.name = ] by the property name "Name =" and only then the code worked without having to use the same conditional statement in the getter property too.
One thing is that the constructor gets the arguments and assigns them the private attributes directly, but those attributes will not get those values unless the setter property processes the values first? isn't that how it works?
public class Cat
{
private string name ="Unnamed";
private string color = "Gray";
public string Name
{
get
{
return name;
//if ((name.Length <= 8 && name.Length>=3) && Regex.IsMatch(name, @"^[a-zA-Z]$"))
//{
// return name;
//}
//else
//{
// return "Unnamed";
//}
}
set
{
if ((name.Length <= 8 && name.Length>=3) && Regex.IsMatch(name, @"^[a-zA-Z]$"))
{
name = value;
}
else
{
name = "Unamed";
}
}
}
public string Color
{
get => color;
set => color=value;
}
public Cat(string name, string color)
{
this.name = name;
this.color = color;
}
//public Cat(string name, string color)
//{
// Name = name;
// Color = color;
//}
}
//The following example is what I tried to test if the validation on the setter is working. Cat cat1 = new Cat("Gigi5", "orange"); Console.WriteLine($"{cat1.Name}'s color is {cat1.Color}");
A few things to mention:
For your purposes your regex string wasn't 100% correct. the [a-zA-Z] string only applies to 1 character so you need to denote how many this applies to after the character itself. In this case {3,8} is a quantifier allowing for between 3 and 8 characters of the type [a-zA-Z]. I recommend checking your regex using an online regex tester as it can save a lot of time.
In your Cat constructor method you were setting your private variable "name", whereas your get/set methods apply to the variable "Name".
When you are comparing your input variable in your set method, you are comparing to the private variable "name", however, the value that gets passed to the "set" method is aptly named as "value" before you do anything to it within the method. Hence you need to check the length of "value", not "name" within the set method:
if ((value.Length <= 8 && value.Length >= 3) && Regex.IsMatch(value, @"^[a-zA-Z]{3,8}$"))
public class Cat
{
private string name = "Unnamed";
private string color = "Gray";
public string Name
{
get
{
return name;
}
set
{
if ((value.Length <= 8 && value.Length >= 3) && Regex.IsMatch(value, @"^[a-zA-Z]{3,8}$"))
{
name = value;
}
else
{
name = "Unnamed";
}
}
}
public string Color
{
get => color;
set => color = value;
}
public Cat(string name, string color)
{
this.Name = name;
this.Color = color;
}
static void Main(string[] args)
{
Cat cat1 = new Cat("Gigi5", "orange");
Console.WriteLine($"{cat1.Name}'s color is {cat1.Color}");
}
}