我试图找出变量是简单的bool
还是Nullable<bool>
。
似乎
if(val is Nullable<bool>)
对bool
和Nullable<bool>
变量以及
if(val is bool)
对于bool
和Nullable<bool>
,也会返回true。
基本上,我很有兴趣找出一个简单的bool
变量是 true OR 如果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
(更具体地说,找出任何非空的值并将它们保存在List<string>
中)。但是,当尝试区分对象中的bool
和bool?
类型(第二个Where
语句)时,这会在lambda表达式中出现并发症。
此外,由于该对象也包含一些字符串类型,我试图在我的第一个.Where
语句中排除那些(我目前可能做得不好,因为它似乎不起作用) 。但我的主要目标是区分bool
和bool?
类型。
答案 0 :(得分:11)
有一种简单的方法可以检查变量是否声明为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();
答案 1 :(得分:4)
获取类实例值的代码:
// 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);
答案 2 :(得分:4)
-(void)viewWillDisappear:(BOOL)animated
此时,您有一个typeof(InstViewModel).GetProperties()
.Select(prop => prop.GetValue(ivm, null))
类型的序列。该序列的每个元素都是一个对象,可以是以下之一:
object
。 null
情况可能发生,因为您具有引用类型的属性的空值,或者属于可空值类型的属性的空值;在这里没有办法区分它们。同样,我们也无法区分来自null
值的盒装bool
或来自bool
值的盒装bool
。< / p>
您需要检查属性的类型,而不是属性的值:
bool?
但只过滤到isNullableProperty = property.PropertyType.IsGenericType
&& property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>);
和bool
,然后:
bool?
答案 3 :(得分:3)
在评估布尔属性和可空布尔属性之前,可以区分它们。然后,无需担心他们是评估为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();
为您提供所需的列表。
答案 4 :(得分:2)
这是对最初问题的回答 - 请忽略此问题。
当您“装箱”一个可以为空的值(因此您将其放入object
)时,它会在其基础类型(在您的情况下为bool
)或null
中进行转换。 ..所以,如果你有
bool? value = true;
object value2 = value;
现在value2.GetType() == typeof(bool)
答案 5 :(得分:2)
根据你的问题
基本上,我很感兴趣 ed ,找出一个简单的bool变量是否为真或者Nullable变量是否为空。
判断一个简单的boolVariable是否为真
if(boolVariable){
//bool variable, not nullable
}
判断你的nullableVariable是否为空
if(nullableVariable.HasValue){
//a nullable variable is not null
}
判断可以为空的bool变量是真还是/而不是null,使用??
运算符
if(variable??false){
//then I'm sure that this is not null and has value=true
}
因此,在确定的情况下,您可以将以下代码用于可空的bool和bool变量
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*/
}
答案 6 :(得分:1)
试试这个:
((bool?)val).HasValue
这将返回true
,如果val
是bool
或,如果val
是bool?
,则该值不是null
!((bool?)val).HasValue
。
另一方面,
true
如果val为bool?
且其值为null
,将仅返回use Symfony\Component\Stopwatch\Stopwatch;
include 'vendor/autoload.php';
$toClone = [
['url' => 'http://github.com/symfony/symfony.git', 'dest' => 'C:\tmp\cloneR1'],
['url' => 'http://github.com/laravel/laravel.git', 'dest' => 'C:\tmp\cloneR2'],
['url' => 'http://github.com/rails/rails.git', 'dest' => 'C:\tmp\cloneR3'],
];
$end = count($toClone);
$i = 0;
$deferred = new React\Promise\Deferred();
$fClone = function (\React\EventLoop\Timer\Timer $timer) use (&$i, $deferred, &$toClone, $end) {
$project = array_pop($toClone);
$git = new \GitWrapper\GitWrapper();
$git->setTimeout(3600);
$git->cloneRepository($project['url'], $project['dest']);
$deferred->notify([$i++, $project['url']]);
if ($end <= $i) {
$timer->cancel();
$deferred->resolve();
}
};
$stopwatch = new Stopwatch();
$stopwatch->start('run');
$loop = React\EventLoop\Factory::create();
$loop->addPeriodicTimer(1, $fClone);
$deferred->promise()->then(function () use ($stopwatch) {
echo 'DONE' . PHP_EOL;
$event = $stopwatch->stop('run');
echo 'Run took ' . $event->getDuration() / 1000 . 'sec and ' . $event->getMemory() . ' bytes of memory';
}, null, function ($data) {
echo 'RUN ' . $data[0] . ' - ' . $data[1] . PHP_EOL;
});
$loop->run();
。
在你的情况下,那个测试不够吗?
答案 7 :(得分:1)
试试这个
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();