Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correctly distinguish between bool? and bool in C#

Tags:

c#

reflection

I am trying to find out if a variable is either a simple bool or a Nullable<bool>.

It seems that

if(val is Nullable<bool>)

returns true for both bool and Nullable<bool> variables and

if(val is bool)

also returns true for both bool and Nullable<bool>.

Basically, I am interesting in finding out if a simple bool variable is true OR if a Nullable<bool> variable is not null.

What's the way to do this?

Here is the full code:

List<string> values = typeof(InstViewModel).GetProperties()
                          .Where(prop => prop != "SubCollection" && prop != "ID" && prop != "Name" && prop != "Level")
                          .Select(prop => prop.GetValue(ivm, null))
                          .Where(val => val != null && (val.GetType() != typeof(bool) || (bool)val == true))      //here I'm trying to check if val is bool and true or if bool? and not null
                          .Select(val => val.ToString())
                          .Where(str => str.Length > 0)
                          .ToList();

The InstViewModel object:

 public class InstViewModel
    {
        public string SubCollection { get; set; }
        public string ID { get; set; }
        public string Name { get; set; }
        public string Level { get; set; }
        public bool Uk { get; set; }
        public bool Eu { get; set; }
        public bool Os { get; set; }
        public Nullable<bool> Mobiles { get; set; }
        public Nullable<bool> Landlines { get; set; }
        public Nullable<bool> UkNrs { get; set; }
        public Nullable<bool> IntNrs { get; set; }
}

The point of my code here is to find out if all of the object's values are null (more specifically, to find out any values that are not null and save them in a List<string>). This presents a complication in the lambda expression, however, when trying to distinguish between bool and bool? types in my object (second Where statement).

Additionally, since the object contains some string types as well, I am trying to exclude those in my first .Where statement (which I am probably not doing right at present as it doesn't seem to be working). But my main goal is to distinguish between bool and bool? types.

like image 824
sparta223 Avatar asked Jun 04 '15 10:06

sparta223


People also ask

What is the difference between bool and bool?

The values for a bool are true and false , whereas for BOOL you can use any int value, though TRUE and FALSE macros are defined in the windef. h header. This means that the sizeof operator will yield 1 for bool (the standard states, though, that the size of bool is implementation defined), and 4 for BOOL .

What is the difference between bool and Boolean in C?

There is NO difference whatsoever. You may use either bool or Boolean with exactly the same results.

Is bool and Boolean same?

In computer science, the Boolean (sometimes shortened to Bool) is a data type that has one of two possible values (usually denoted true and false) which is intended to represent the two truth values of logic and Boolean algebra.

What is a bool V?

Boolean variables can either be True or False and are stored as 16-bit (2-byte) values. Boolean variables are displayed as either True or False. Like C, when other numeric data types are converted to Boolean values then a 0 becomes False and any other values become True.


2 Answers

There is a simple way to check whether a variable is declared as T or T?:

private static bool IsNullable<T>(T val)
{
    return false;
}

private static bool IsNullable<T>(T? val)
    where T : struct
{
    return true;
}

Usage:

bool? val = false;

if (IsNullable(val))
{
    ...
}

EDIT
Try the following code for edited question:

var boolProps = typeof (InstViewModel).GetProperties()
    .Where(prop => prop.PropertyType == typeof(bool))
    .Select(prop => (bool)prop.GetValue(ivm, null))
    .Select(v => v ? v.ToString() : String.Empty);

var nullableBoolProps = typeof(InstViewModel).GetProperties()
    .Where(prop => prop.PropertyType == typeof(bool?))
    .Select(prop => (bool?)prop.GetValue(ivm, null))
    .Select(v => v.HasValue ? v.ToString() : String.Empty);

List<string> values = boolProps.Concat(nullableBoolProps)
              .Where(str => str.Length != 0)
              .ToList();
like image 142
Dmitry Avatar answered Sep 25 '22 09:09

Dmitry


Code for getting class instance values:

// create class instance
InstViewModel model = new InstViewModel()
{
    Uk = true,
    UkNrs = false,
};

// check all boolean fields are false or null
bool isAllNullOrFalse = (from property in typeof(InstViewModel).GetProperties()
                         let type = property.PropertyType
                         let isBool = type == typeof(bool)
                         where isBool || type == typeof(bool?)
                         let value = property.GetValue(model)
                         select value == null || (isBool && bool.Equals(value, false))).All(e => e);

Console.WriteLine("All values are null or false = {0}", isAllNullOrFalse);
like image 33
General-Doomer Avatar answered Sep 24 '22 09:09

General-Doomer