С#: ключевое слово '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...
Ответы
Ответ 1
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...
Ответ 2
Вы можете сделать это следующим образом:
object a = new StreamWriter("c:\\temp\\test.txt");
if (a is TextReader == false)
{
Console.WriteLine("failed");
}
Ответ 3
Почему бы просто не использовать else?
if (child is IContainer)
{
//
}
else
{
// Do what you want here
}
Его опрятный он знакомый и простой?
Ответ 4
У вас все хорошо, но вы можете создать набор методов расширения, чтобы сделать "более элегантный способ проверки экземпляра" НЕ "".
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
Гадкий? Я не согласен. Единственный другой способ (я лично считаю, что это "уродливый" ):
var obj = child as IContainer;
if(obj == null)
{
//child "aint" IContainer
}
Ответ 6
Оператор is
вычисляет логический результат, поэтому вы можете делать все, что в противном случае вы могли бы сделать на bool. Чтобы отменить это, используйте оператор !
. Зачем вам нужен другой оператор только для этого?
Ответ 7
Метод расширения 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
}
В вашем случае это не имеет значения, поскольку вы возвращаетесь из метода. Другими словами, будьте осторожны, чтобы не выполнять как проверку типа, а затем преобразование типа сразу после.
Ответ 8
В то время как оператор IS обычно является лучшим способом, существует альтернатива, которую вы можете использовать в некоторых условиях. Вы можете использовать оператор as и проверить значение null.
MyClass mc = foo as MyClass;
if ( mc == null ) { }
else {}
Ответ 9
Хотя это не устраняет проблему с круглыми скобками, ради людей, попадающих сюда через Google, следует отметить, что существует более новый синтаксис (начиная с С# 7), чтобы сделать остальную часть вашего кода немного чище:
if (!(DocumentPart is IContainer container)) { return; }
foreach(DocumentPart child in container.Children) {
...
Это позволяет избежать двойного приведения, нулевой проверки и наличия переменной, доступной в областях, где она может быть нулевой.
Ответ 10
Это еще не было упомянуто. Это работает, и я думаю, что это выглядит лучше, чем использование !(child is IContainer)
if (part is IContainer is false)
{
return;
}
Ответ 11
if (child is IContainer ? false : true)