C #: ключевое слово is и проверка на Not - PullRequest
252 голосов
/ 01 мая 2009

Это глупый вопрос, но вы можете использовать этот код, чтобы проверить, относится ли что-то к определенному типу ...

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

Есть ли более элегантный способ проверить наличие экземпляра "НЕ"?

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...

Ответы [ 11 ]

273 голосов
/ 01 мая 2009
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...
105 голосов
/ 01 мая 2009

Вы можете сделать это так:

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

if (a is TextReader == false)
{
   Console.WriteLine("failed");
}
12 голосов
/ 01 мая 2009

Почему бы просто не использовать остальное?

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

Это хорошо, это знакомо и просто?

8 голосов
/ 01 мая 2009

То, как у вас это хорошо, но вы могли бы создать набор методов расширения, чтобы сделать "более элегантный способ проверки наличия экземпляра 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
}
5 голосов
/ 01 мая 2009

Гадкий? Я не согласен. Единственный другой способ (лично я считаю, что это «уродливее»):

var obj = child as IContainer;
if(obj == null)
{
   //child "aint" IContainer
}
3 голосов
/ 01 мая 2009

Метод расширения 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
}

В вашем случае это не имеет значения, так как вы возвращаетесь из метода. Другими словами, будьте осторожны, чтобы не выполнять как проверку типа, так и преобразование типа сразу после.

3 голосов
/ 01 мая 2009

Оператор is оценивает логический результат, поэтому вы можете делать все, что в противном случае вы могли бы делать в bool. Чтобы отрицать это, используйте оператор !. Зачем вам нужен другой оператор только для этого?

2 голосов
/ 01 мая 2009

Хотя оператор IS обычно является наилучшим способом, есть альтернатива, которую вы можете использовать при некоторых обстоятельствах. Вы можете использовать как оператор и проверить на ноль.

MyClass mc = foo as MyClass;
if ( mc == null ) { }
else {}
1 голос
/ 23 января 2019

Это еще не было упомянуто. Это работает, и я думаю, что это выглядит лучше, чем при использовании !(child is IContainer)

if (part is IContainer is false)
{
    return;
}
1 голос
/ 07 марта 2018

Хотя это не устраняет проблему с круглыми скобками, ради людей, попадающих сюда через Google, следует отметить, что существует более новый синтаксис (начиная с C # 7), чтобы сделать остальную часть вашего кода немного чище:

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

Это позволяет избежать двойного приведения, проверки на нуль и наличия переменной, доступной в областях, где она может быть нулевой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...