正确区分布尔值?和 C# 中的布尔值



我试图找出变量是简单的bool还是Nullable<bool>

看来

if(val is Nullable<bool>)

对于boolNullable<bool>变量都返回 true,并且

if(val is bool)

对于boolNullable<bool>也返回 true。

基本上,我感兴趣的是找出一个简单的bool变量是否为真,或者Nullable<bool>变量是否不为空

有什么方法可以做到这一点?

以下是完整的代码:

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();

InstViewModel对象:

 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; }
}

我的代码在这里的重点是找出是否null对象的所有值(更具体地说,找出任何非 null 的值并将它们保存在 List<string> 中(。但是,当尝试区分对象中的boolbool?类型时,这给 lambda 表达式带来了复杂性(第二个Where语句(。

此外,由于该对象也包含一些字符串类型,因此我试图在我的第一个.Where语句中排除这些类型(我目前可能做得不正确,因为它似乎不起作用(。但我的主要目标是区分boolbool?类型。

有一种简单的方法可以检查变量是声明为 T 还是T?

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

用法:

bool? val = false;
if (IsNullable(val))
{
    ...
}

编辑
尝试以下代码进行编辑问题:

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();

获取类实例值的代码:

// 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);
typeof(InstViewModel).GetProperties()
  .Select(prop => prop.GetValue(ivm, null))

此时,您有一个类型 object 的序列。该序列的每个元素都将是一个对象,可以是以下对象之一:

  1. 引用类型的实例。
  2. 值类型的装箱实例。
  3. null .

null情况可能会发生,因为引用类型的属性具有 null 值,或者对于可为 null 值类型的属性具有 null 值;此处无法区分。同样,也无法区分来自bool值的盒装bool和来自bool?值的盒装bool

您需要检查属性的类型,而不是属性的值:

isNullableProperty = property.PropertyType.IsGenericType
  && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>);

但是,只需过滤到仅boolbool?

typeof(InstViewModel).GetProperties()
  .Where(
     prop => prop.PropertyType == typeof(bool)
     || prop.PropertyType == typeof(bool?))

在计算布尔属性和可为 null 的布尔属性之前,可以对其进行区分。 那么就不用担心他们的评估是bool还是Nullable<bool>

var nullableBooleanProperties = typeof(InstViewModel).Where(prop => prop.PropertyType == typeof(bool?));

然后你可以简单地将这些写到字符串列表中:

var values = nullableBooleanProperties.Select(prop => prop.GetValue(ivm)).Where(val => val != null).Select(val => val.ToString());

将这些放在一起可以得到:

var values = typeof(InstViewModel).Where(prop => prop.PropertyType == typeof(bool?))
    .Select(prop => prop.GetValue(ivm)).Where(val => val != null)
    .Select(val => val.ToString())
    .ToList();

这为您提供了所需的列表。

根据您的问题

基本上,我有兴趣找出一个简单的布尔变量是否为真,或者一个可为空的变量是否不为空。

  • 判断一个简单的布尔变量是否为真

     if(boolVariable){
          //bool variable, not nullable
     }
    
  • 判断你的 nullableVariable 是否不为 null

     if(nullableVariable.HasValue){
         //a nullable variable is not null
     }
    
  • 要判断可为 null 的布尔变量是真还是/和不为空,请使用 ?? 运算符

    if(variable??false){
       //then I'm sure that this is not null and has value=true
    }
    

因此,在确定性中,您可以对可为空的布尔值和布尔变量使用以下代码

     if(variables!=null &&variables!=false){/*This may give a warning message but it works*/}

   if(((bool?)variable)??false){
      /*variable is not null and is true*/
    }

这是对最初问题的回答 - 忽略这一点。

当您"装箱"一个可为空的值(因此将其放在object中(时,它会在其底层类型(bool在您的情况下(或null中转换...所以如果你有

bool? value = true;
object value2 = value; 

现在value2.GetType() == typeof(bool)

试试这个

List<string> values = typeof(InstViewModel).GetProperties()
    .Select(prop => new { N = prop.Name, T = prop.PropertyType, V = prop.GetValue(ivm, null) })
    .Where(prop => prop.N != "SubCollection" && prop.N != "ID" && prop.N != "Name" && prop.N != "Level")
    .Where(val => (val.V != null && val.T.IsAssignableFrom(typeof(Nullable<bool>))) || Convert.ToBoolean(val.V))                    
    .Select(val => val.V.ToString())
    .Where(str => str.Length > 0)
    .ToList();

试试这个:

((bool?)val).HasValue

这将返回true,如果valbool或者如果val是值不nullbool?

另一方面

!((bool?)val).HasValue

仅当 val bool? 且其值为 null 时,才会返回true

在你的情况下,这个测试还不够吗?

相关内容

  • 没有找到相关文章

最新更新