c#: 'is'关键字和检查Not

这是一个愚蠢的问题,但您可以使用这段代码来检查某项是否为特定类型…

if (child is IContainer) { //....

是否有更优雅的方法来检查“NOT”实例?

if (!(child is IContainer)) { //A little ugly... silly, yes I know...


//these don't work :)
if (child !is IContainer) {
if (child isnt IContainer) {
if (child aint IContainer) {
if (child isnotafreaking IContainer) {

是的,是的……愚蠢的问题……

因为有一些问题的代码看起来像什么,它只是一个简单的返回在一个方法的开始。

public void Update(DocumentPart part) {
part.Update();
if (!(DocumentPart is IContainer)) { return; }
foreach(DocumentPart child in ((IContainer)part).Children) {
//...etc...
129299 次浏览
if(!(child is IContainer))

是唯一的操作符(没有IsNot操作符)。

你可以构建一个扩展方法:

public static bool IsA<T>(this object obj) {
return obj is T;
}

然后用它来:

if (!child.IsA<IContainer>())

你可以继续你的主题:

public static bool IsNotAFreaking<T>(this object obj) {
return !(obj is T);
}


if (child.IsNotAFreaking<IContainer>()) { // ...

更新(考虑OP的代码片段):

因为你实际上是在后面强制转换值,所以你可以直接使用as:

public void Update(DocumentPart part) {
part.Update();
IContainer containerPart = part as IContainer;
if(containerPart == null) return;
foreach(DocumentPart child in containerPart.Children) { // omit the cast.
//...etc...

为什么不直接使用else ?

if (child is IContainer)
{
//
}
else
{
// Do what you want here
}

它的整洁,熟悉和简单?

丑吗?我不同意。唯一的另一种方式(我个人认为这更“丑陋”):

var obj = child as IContainer;
if(obj == null)
{
//child "aint" IContainer
}

虽然IS操作符通常是最好的方法,但在某些情况下,您可以使用另一种替代方法。您可以使用as操作符并测试为空。

MyClass mc = foo as MyClass;
if ( mc == null ) { }
else {}

is操作符的计算结果是布尔值,所以你可以做任何在bool类型上可以做的事情。要对其求反,请使用!操作符。为什么要用不同的运算符呢?

你拥有它的方式很好,但你可以创建了一组扩展方法,以“更优雅的方式检查'NOT'实例”。

public static bool Is<T>(this object myObject)
{
return (myObject is T);
}


public static bool IsNot<T>(this object myObject)
{
return !(myObject is T);
}

然后你可以这样写:

if (child.IsNot<IContainer>())
{
// child is not an IContainer
}

你可以这样做:

object a = new StreamWriter("c:\\temp\\test.txt");


if (a is TextReader == false)
{
Console.WriteLine("failed");
}

扩展方法IsNot<T>是扩展语法的好方法。记住

var container = child as IContainer;
if(container != null)
{
// do something w/ contianer
}

表现得比做

if(child is IContainer)
{
var container = child as IContainer;
// do something w/ container
}

在您的情况下,这并不重要,因为您正在从方法返回。换句话说,要注意不要同时进行类型检查和类型转换。

if (child is IContainer ? false : true)

虽然这并不能避免圆括号的问题,但为了让人们通过谷歌到达这里,应该提到的是存在更新的语法(从c# 7开始),以使您的其余代码更干净:

if (!(DocumentPart is IContainer container)) { return; }
foreach(DocumentPart child in container.Children) {
...

这避免了双重强制转换、null检查以及在可能为空的作用域中使用变量。

新增在c# 9.0中

https://devblogs.microsoft.com/dotnet/welcome-to-c-9-0/#logical-patterns

if (part is not IContainer)
{
return;
}

原来的答案

这一点还没有被提及。它工作,我认为它看起来比使用!(child is IContainer)更好

if (part is IContainer is false)
{
return;
}

c# 9(随.NET 5发布)包括逻辑模式andornot,这使我们能够更优雅地编写:

if (child is not IContainer) { ... }

同样,这个模式也可以用来检查null:

if (child is not null) { ... }

我要用这个

如果(!(对象是Car)){