Check null or empty string - c#

I would like to display 'reason not explicited' if the user doesn't fill this field or the user input if he fills it.
With this code, I don't understand why but even if I fill the field, it is going to display 'reason not explicited'.
private string reason;
public string Reason
{
get
{
return this.reason;
}
set
{
if (string.IsNullOrEmpty(this.Reason))
this.reason = "reason not explicited";
else this.reason = value;
}
}
[Pure]
public static bool IsNullOrEmpty(String value) {
return (value == null || value.Length == 0);
}

just use value in your setter to handle the correct behavior
set
{
if (string.IsNullOrEmpty(value))
this.reason = "reason not explicited";
else
this.reason = value;
}

Because you are checking the property instead of the value.
Your current code sets the value of the property only if it's null or empty.
It should be
set
{
if (string.IsNullOrEmpty(value))
this.reason = "reason not explicited";
else this.reason = value;
}
Or even better:
set
{
this.reason = (string.IsNullOrEmpty(value)) ? "reason not explicited": value;
}

You have to check value, not this.Reason:
public string Reason
{
get
{
return this.reason;
}
set
{
this.reason = string.IsNullOrEmpty(value)
? "reason not explicited"
: value;
}
}

The problem is in this line of code
if (string.IsNullOrEmpty(this.Reason))
When you are trying to get the value of this property, calls it's getter, which returns value of reason field. And this field is not filled with correct value at the moment you are trying to get value of it.
So you should modify your code to check if null or empty string of concrete input value:
if (string.IsNullOrEmpty(value))

you need to pass value to the function IsNullOrEmpty function
if (string.IsNullOrEmpty(value))
this.reason = "reason not explicited";
else this.reason = value;

The setter will trigger when you change(assign) the value, so if the user skip that field means the setter will not trigger. But the getter will trigger when you access the value of the property. So in your case if you apply the logic inside the get means it will display the "reason not explicited" if the reason is null or empty. So the new logic would be like the following:
get
{
if (string.IsNullOrEmpty(this.reason))
return "reason not explicited";
else this.reason = value;
return this.reason;
}
set
{
this.reason = value;
}
Another solution will be like this:
Initialize the backup property with the "reason not explicited" so even if the user skip the field(setter will not trigger) you will get the default value to be printed. And you have to update the backup property based on the value
private string reason = "reason not explicited";
public string Reason
{
get { return this.reason; }
set
{
if (String.IsNullOrEmpty(value))
this.reason = "reason not explicited";
else
this.reason = value;
}
}

You might do an extension method to IsNullOrEmpty():
public static bool IsNullOrEmpty(this string value) => string.IsNullOrEmpty(str);
And then you can use it this way:
set { this.reason = value.IsNullOrEmpty() ? "reason not explicited" : value; }

Related

checking in the model for nulls

I like to check the model for nulls before I use the value in the view. Is this the correct way to use the get and set? I am getting an Exception of type 'System.StackOverflowException' was thrown." on the this.MiddleInitial = value;
Model
public string MiddleInitial {
get {
if (string.IsNullOrWhiteSpace(MiddleInitial) == true) {
return MiddleInitial;
}
return $ "{MiddleInitial.Trim()}.";
}
set {
this.MiddleInitial = value;
}
}
Updated Model
public string MiddleInitial {
get {
if (string.IsNullOrWhiteSpace(MiddleInitial) == true) {
return MiddleInitial;
}
return $ "{MiddleInitial.Trim()}.";
}
set {
if (string.IsNullOrWhiteSpace(MiddleInitial) == true) {
return MiddleInitial;
}
return $ "{MiddleInitial.Trim()}.";
}
}
Inside your get method's if condition, you should check false, not true. Like below:
get
{
//if (string.IsNullOrWhiteSpace(MiddleInitial) == true)
if (string.IsNullOrWhiteSpace(MiddleInitial) == false)
{
return MiddleInitial;
}
return $"{MiddleInitial.Trim()}.";
}
Using an internal private backing field for the property allows you a fine control on what goes into the property and what you return back
// The blank value should be the default for the property
private string _middleInitial = "";
public string MiddleInitial
{
get { return _middleInitial; }
// When someone tries to set a new value for the property
// check for Invalid values (in this case a null ) and
// reset the property back to the default
// (or even throw an exception if it is the case)
set
{
_middleInitial = (value == null ? "" : value.Trim());
// if(value == null)
// throw new ArgumentException("Null is not accepted");
// else
// _middleInitial = value.Trim();
}
}

Throw an error when the user enter null or empty string

I'm attempting to resolve the following exercise:
You need to create a class named Product that represents a product.
The class has a single property named Name. Users of the Product class
should be able to get and set the value of the Name property. However,
any attempt to set the value of Name to an empty string or a null
value should raise an exception. Also, users of the Product class
should not be able to access any other data members of the Product
class. How will you create such a class?
I have created the following code but for some reason it does not throw the exception when the string is invalid:
class Program
{
static void Main(string[] args)
{
Product newProduct = new Product();
Console.WriteLine("Enter Product name:");
newProduct.Name = null; //Console.ReadLine();
Console.WriteLine("Product name is : {0}", newProduct.Name);
Console.ReadLine();
}
}
class Product
{
private string name;
public string Name
{
get
{
return this.name;
}
set
{
if (Name != String.Empty || Name != null)
{
name = value;
}
else
{
throw new ArgumentException("Name cannot be null or empty string", "Name");
}
}
}
}
Is the exception not thrown because I do not have try-catch statement?
I was also wondering is it possible to have only catch statement without try statement?
Use String.IsNullOrEmpty Method (String). Change your set like this:
set
{
if (!string.IsNullOrEmpty(value))
{
name = value;
}
else
{
throw new ArgumentException("Name cannot be null or empty string", "value");
}
}
Also you can use String.IsNullOrWhiteSpace Method (String) that Indicates whether a specified string is null, empty, or consists only of white-space characters.
Your if state is wrong. Let's do a truth table:
if (value != String.Empty || value != null)
Name = null True Or False = True
Name = "name" True Or True = True
Name = "" False Or True = True
Your if statement is always true!
I would re-write it thus:
if (value == String.Empty || value == null)
{
throw new ArgumentException("Name cannot be null or empty string", "Name");
}
else
{
name = value;
}
you could just change the Or to and AND but I think the above reads better (the below has an unnecessary double negative):
if (value != String.Empty && value != null)
{
name = value;
}
else
{
throw new ArgumentException("Name cannot be null or empty string", "value");
}
As Dmitry Bychenko says, I didn't notice you were not testing for value. In getters you should use the value property. Not the name of your property
The second parameter (again pointed out by Dmitry Bychenko) in your exception should be:
The name of the parameter that caused the current exception.
MSDN
which in your case is the string "value":
throw new ArgumentException("Name cannot be null or empty string", "value");
If you want different exceptions on null and on empty string (often null means that something is totally wrong, when empty string is just a format error):
public string Name {
get {
return name;
}
set {
if (null == value)
throw new AgrumentNullException("value");
else if (String.Equals(value, ""))
throw new AgrumentException("Empty values are not allowed.", "value");
name = value;
}
}
In case you don't want to distiguish them:
public string Name {
get {
return name;
}
set {
if (String.IsNullOrEmpty(value))
throw new AgrumentException("Null or empty values are not allowed.", "value");
name = value;
}
}
Note, that in both cases it's value that you have to test, not a property Name. In your original code the name's (and so Name as well) initial value is null and you'll get exception whatever you try to set.

have email and phone number in correct format using a object class

I am trying to make a contact class for my contact managers application and I need to have email have to contain 1 and only 1 # symbol and make sure the phone number is in the format 123-456-7890 but I am not sure how to do this.
Any guidance would be appreciated
class Contact
{
class Contact
{
//private member variables
private String _firstName;
private String _lastName;
private Type _contactTypes;
private String _phoneNumber;
private String _emailAddress;
//Public constructor that takes five arguments
public Contact()
{
//Call the appropriate setter (e.g. FirstName) to set the member variable value
/* GetFirstName = firstName;
GetLastName = lastName;
ContactTypes = contactTypes;
GetPhoneNumber = phoneNumber;
GetEmailAddress = emailAddress;*/
}
/*********************************************************************
* Public accessors used to get and set private member variable values
*********************************************************************/
//Public ContactTypes accessor
public Type ContactTypes
{
get
{
//Return member variable value
return _contactTypes;
}
set
{
//Validate value and throw exception if necessary
if (value == null)
throw new Exception("ContactType must have a value");
else
//Otherwise set member variable value*/
_contactTypes = value;
}
}
enum ContactTypesEnum { Family, Friend, Professional }
//Public FirstName accessor: Pascal casing
public String GetFirstName
{
get
{
//Return member variable value
return _firstName;
}
set
{
//Validate value and throw exception if necessary
if (value == "")
throw new Exception("First name must have a value");
else
//Otherwise set member variable value
_firstName = value;
}
}
//Public LastName accessor: Pascal casing
public String GetLastName
{
get
{
//Return member variable value
return _lastName;
}
set
{
//Validate value and throw exception if necessary
if (value == "")
throw new Exception("Last name must have a value");
else
//Otherwise set member variable value
_lastName = value;
}
}
//Public PhoneNumber accessor
public String GetPhoneNumber
{
get
{
//Return member variable value
return _phoneNumber;
}
set
{
bool isValid = Regex.IsMatch(value, #"/d{3}-/d{3}-/d{4}");
//Validate value and throw exception if necessary
if (value == "")
throw new Exception("PhoneNumber must have a value");
else
//Otherwise set member variable value
_phoneNumber = value;
}
}
//Public Email accessor
public String GetEmailAddress
{
get
{
//Return member variable value
return _emailAddress;
}
set
{
//Validate value and throw exception if necessary
if (value == "")
throw new Exception("EmailAddress must have a value");
else
//Otherwise set member variable value
_emailAddress = value;
}
}
}
}
I agree with the comment from #Enigmativity - it's not a good idea to throw exceptions in your accessor set functions. That being said, you're already halfway there with your isValid regular expression test in GetPhoneNumber.
set
{
bool isValid = Regex.IsMatch(value, #"/d{3}-/d{3}-/d{4}");
if (isValid) // Set member variable value
_phoneNumber = value;
}
You can either do a similar regular expression test for your email or use System.Net.Mail.MailAddress class. See this SO response.

How can I make a field in a class be set to false if the value being set is a null?

I have the following:
var result2 = result1
.Select((t, index) => new {
Answer = t.Answer,
Answers = JSON.FromJSONString<Answer2>(t.AnswerJSON)
});
return Ok(result2);
public class Answer2 {
public bool? Correct; // Maybe this should be a property
public bool Response; // Maybe this should be a property
}
And my String > object function:
public static T FromJSONString<T>(this string obj) where T : class
{
if (obj == null)
{
return null;
}
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(obj)))
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
T ret = (T)ser.ReadObject(stream);
return ret;
}
}
Is there a way with this that I could make the Response field be false if a null is present for Response in the JSON string or if there is no value for Response in the JSON string?
Note: I had a suggestion about using a property and I think that would work but I am not sure how to do it in practice.
You should use a property for this matter:
public class Answer2 {
private bool correct; // This field has no need to be nullable
public bool? Correct
{
get { return correct; }
set { correct = value.GetValueOrDefault(); }
}
}
Following the Q and A section, you should be able to do it on a property like this:
private bool? whatever;
public bool? Whatever
{
get { return whatever; }
set
{
if (value == null)
whatever = false;
else
whatever = value;
}
}
This way you can pass a null value to the property, but it can only have a bool (true/false) value in it.

what is the correct way to compare two values in property notification?

I have this simple property which implement property change notification:
public SolidColorBrush Color
{
get
{
return this.color;
}
set
{
if (this.color == value)
{
return;
}
this.color = value;
this.NotifyOfPropertyChange(() => this.Color);
}
}
I am using Resharper + stylecop. I am getting this warning for above code (on if (this.color == value) :
Possible unintended reference comparison, to get value comparison, use Equals.
I used equals as follow:
public SolidColorBrush Color
{
get
{
return this.color;
}
set
{
if (Equals(this.color, value))
{
return;
}
this.color = value;
this.NotifyOfPropertyChange(() => this.Color);
}
}
Then I am getting warning that:
The call to Equals must begin with the 'this','base','object' or linemodel or propertychangeBase prefix to indicate the intended method call (stylecope rule SA1126]
So I change it to:
public SolidColorBrush Color
{
get
{
return this.color;
}
set
{
if (SolidColorBrush.Equals(this.color, value))
{
return;
}
this.color = value;
this.NotifyOfPropertyChange(() => this.Color);
}
}
Now I am getting this warning:
Qualifier is redundant.
Access to a static member of a type via a derived type
I changed the code to:
public SolidColorBrush Color
{
get
{
return this.color;
}
set
{
if (object.Equals(this.color, value))
{
return;
}
this.color = value;
this.NotifyOfPropertyChange(() => this.Color);
}
}
No I am getting the warning that (on object.Equals):
Qualifier is redundant
So what is the right way to compare these two values? Any standard way to do this comparison that works always correctly?
1) SolidColorBrush is a reference type and it doesn't overload == operator, so using == operator to compare it will do reference comparison. Resharper warns you as you may not know that.
Instead you could do
if (this.color.Color == value.Color)
{
return;
}
Note: You need to take care of null references.
2) I guess it is style cop's warning(I'm not familiar with this), I'm pretty sure it is same as 3(To avoid confusion later, say which method you need to call clearly).
3) It says that you're calling Object.Equals method with SolidColorBrush.Equals(derived type). It is not a problem, but later if SolidColorBrush adds a Equals method with same parameters you'll end up calling a different method which you doesn't intended to do. That's why resharper warns you.
Try sth like this if (color.Equals(value))
a full comparison from SolidColorBrush could be done by comparing the underlying color struct values by utilizing the Equals overload from Color class
sample
public SolidColorBrush Color
{
get
{
return this.color;
}
set
{
if (color != null && value != null)
{
if (color.Color.Equals(value.Color))
return;
}
else if (color == null && value == null)
return;
this.color = value;
}
}

Categories

Resources