web-dev-qa-db-ja.com

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...
256
Hugoware
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...
278
Mehrdad Afshari

次の方法で実行できます。

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

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

なぜelseを使用しないのですか?

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

そのきちんとしたそれは身近でシンプルですか?

12
Mark Broadhurst

方法は問題ありませんが、could拡張メソッドのセットを作成して、「 '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
}
8
Robert Cartaino

醜い?同意しません。他の唯一の方法(私は個人的にこれは「 "い」と思います):

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

拡張メソッド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
Jeff

is演算子はブール値の結果に評価されるため、boolでできることなら何でもできます。否定するには、!演算子を使用します。なぜこれだけのために別の演算子が必要なのでしょうか?

3
Brian Rasmussen

これはまだ言及されていません。それは機能し、!(child is IContainer)を使用するよりも良く見えると思います

if (part is IContainer is false)
{
    return;
}
2
Todd Skelton

通常、IS演算子が最善の方法ですが、状況によっては使用できる代替手段があります。 as演算子を使用して、nullをテストできます。

MyClass mc = foo as MyClass;
if ( mc == null ) { }
else {}
2
Muad'Dib

これは括弧の問題を回避しませんが、Google経由でここにアクセスする人のために、コードの残りの部分を少しきれいにするための新しい構文(C#7以降)が存在することに注意してください。

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

これにより、二重キャスト、nullチェック、および変数がnullになる可能性のあるスコープで変数を使用できなくなります。

1
if (child is IContainer ? false : true)
0
Ternary