简体   繁体   中英

C# - Check if integer property is set

I'm validating some properties and I need to know if long or integer values are set by other layers.

For example, this class::

public class Person 
{
    public int Age {get;set;}
}

When I set a new instance of Person , the Age gets the value 0. But I have to validate if the Age were set, because the Age can be zero (not in this context of course).

One solution that I've thought of is to use the int as a nullable integer ( public int? Age ) and in the constructor of Person set the Age as null.

But I'm trying to avoid it because I would have to change too many classes just to check if Age.HasValue and to use it as Age.Value .

Any suggestions?

Int's are by default initialized to 0; Assuming you don't want to use int? which would work perfectly for you. You can check against that or you can have a flag and a backing field:

private int _age;
public int Age 
{ 
  get { return _age; } 
  set { _age = value; _hasAge = true; } 
}

public bool HasAge { get { return _hasAge; } }

As suggested above you can initialize it to an invalid state:

private int _age = -1;
public int Age 
{ 
  get { return _age; } 
  set { _age = value; _hasAge = true; } 
}

public bool HasAge { get { return _age != -1; } }

Or just break down and use an int?

public int? Age { get; set; }
public bool HasAge { get { return Age.HasValue; } }

For backwards compatability with your code, you can back it off an int? without exposing it:

private int? _age;
public int Age
{
  get { return _age.GetValueOrDefault(-1); }
  set { _age = value; }
}

public bool HasAge { get { return _age.HasValue; } }

There's no difference between a field (or automatically implemented property) which has been explicitly set to its default value, and one which has never been set.

A Nullable<int> is definitely the way to go here - but you'll need to consider the cleanest API to use.

For example, you might want:

public class Person 
{
    private int? age;

    public int Age
    {
        // Will throw if age hasn't been set
        get { return age.Value; }
        // Implicit conversion from int to int?
        set { age = value; }
    }

    public bool HasAge { get { return age.HasValue; } }
}

That will allow you to read Age directly in places which assume it's been set - but test for it when they want to be careful.

Whatever pattern you use, you will have to have an "is set" query before you get the value, so...

Use a nullable field int? age int? age which your get/set properties use, and query an IsAgeSet property:

public class Person  
{ 
    private int? age;

    public int Age {
        get {return age.Value;} // will fail if called and age is null, but that's your problem......
        set {age = value;}
    }
    public bool IsAgeSet {
        get {return age.HasValue;}
    }
}

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