2016-09-12 18 views
0

私はリストに.Where()メソッドを使用しようとすると、リストは、ジェネリック型である場合、このメソッドが定義されていないようだん:私のプログラムでは。ジェネリック型リストにメソッドが定義されていませんか?

、私はWarningというクラスがあり、別の中クラス、警告のリストとして定義:

Dim warningList As List(Of Warning) 

私は、このリストを操作しよう:

Dim item = warningList.Where(Function(x) x.GetName() = "Foo").FirstOrDefault() 

これは完全に正常に動作しますが、私はこのようにそれをしようとすると:

Dim itemList 
if(type = "Warning") Then 'Please note that this condition is true... 
    itemList = warningList 
End If 

Dim item = itemList.Where(Function(x) x.GetName() = "Foo").FirstOrDefault() 

私はその方法.Where()を述べ、例外を取得は、クラスWarning

のために定義されていませんこれは、なぜ誰も教えてもらえますか? ありがとうございました!

+1

実際のコードではありません。 'warningList'が本当に' List(Of Warning) 'であれば' Enumerable.Where'(LINQがインポートされている場合)を使うことができます。このインスタンスを別の変数(宣言上)に割り当てるという事実は、その変数の型も 'List(Of Warning)'なので何も変更しません。だから 'itemList.Where'もうまくいくはずです。 'Where'で拡張された型は' IEnumerable(Of T) 'であり、' T'は任意の型( 'Object')であってもよいので、'警告 'はそれとは関係ありません。 'List(Of T)'は 'IEnumerable(Of T)'を実装しているので、任意のリスト(または配列)で 'Enumerable.Where'を使うことができます。 –

+0

あなたはそうです、私はちょうどこのコードだけのテストプロジェクトを作成しました。それはうまくいくようですので、私は本当の問題が何であるかを調べます...これを指摘してくれてありがとう! – DrDonut

+0

@TimSchmelter:今、私の質問に適応しました。それは違いを生む 'If'ステートメントのようですか?今私のテストプロジェクトで同じ動作をしています... – DrDonut

答えて

1

あなたの質問を編集したので、それは明らかです。それは(私は強く反対をお勧めしますOffにオプション厳格なセットとVB.NETで)暗黙的Objectをですので

あなたは、タイプなしitemListを宣言

Object型の変数を宣言したので、任意の型を割り当てることができます。 。しかし、あなたは

IEnumerable(Of T)を拡張したリストまたはLINQのメソッドを(使用できるように、その実数型List(Of Warning)に戻ってそれをキャストする必要がしかし、その代わりに、正しいタイプでそれを宣言します:

Dim itemList As List(Of Warning) 
if(type = "Warning") Then 
    itemList = warningList 
End If 

Dim item = itemList.Where(Function(x) x.GetName() = "Foo").FirstOrDefault() 

はコメントを含めますWarningがこの問題に関連していない理由を説明します。

実際のコードではありませんwarningListが本当にList(Of Warning) あなたがを使用することができるはずである場合(LINQがインポートされた場合は )。このインスタンスを別の変数 (宣言時)に割り当てるという事実は、その変数の型が でもList(Of Warning)であるため、何も変更されません。だからitemList.Whereもうまくいくはずです。 Warning は、Where で拡張されるタイプがIEnumerable(Of T)であるため、Tはどのタイプ(さらにはObject)でもかまいません。 List(Of T)IEnumerable(Of T)を実装しているので、いずれのリストにもEnumerable.Whereを使用できます。 (または配列)


あなたは、実際には複数の種類があり、Warning 1つだけそれのある場合は、共通のインタフェースを実装する必要があります。ここでは例です:

Public Enum NotificationType 
    Warning 
    Info 
    [Error] 
End Enum 

Public Interface INamedNotification 
    ReadOnly Property Type As NotificationType 
    Property Name As string 
End Interface 

Public Class Warning 
    Implements INamedNotification 
    Public Sub New(name As String) 
     Me.Name = name 
    End Sub 
    Public Property Name As String Implements INamedNotification.Name 
    Public ReadOnly Property Type As NotificationType Implements INamedNotification.Type 
     Get 
      Return NotificationType.Warning 
     End Get 
    End Property 
End Class 

今、あなたはList(Of INamedNotification)を宣言し、Warningクラスのようなものは何でも実装し、このインタフェース、とそれを埋めることができます。

Dim notificationList As List(Of INamedNotification) 
if type = "Warning" Then 
    itemList = warningList 
Else If type = "Info" 
    itemList = infoList 
End If 

Dim item = notificationList.Where(Function(x) x.Name = "Foo").FirstOrDefault() 
+0

あなたは先生、天才です!私は、空の変数に値が代入されたとき、実行時に暗黙的に 'List(Of Warning) 'へのキャストを行うと常に考えていました。私は間違っていた。ありがとうございました! – DrDonut

+0

@DrDonut:Option StrictをONに変更することを本当に考えてください。多くのコンパイラエラーが発生しますが、実際に.NETとタイプシステムについて理解するのに役立ちます。それ以外の場合は、常にそのような問題に脆弱です。異なるが関連するタイプのリストが複数ある場合は、私の答えを編集してあなたの方法を示すことに注意してください。 –

+0

ありがとう!しましょう。 – DrDonut

関連する問題