2011-07-01 11 views
5

ho qualcosa di simile:C# Usa oggetto piuttosto che di riferimento per List.Contains()

public class MyClass 
{ 
    public string Type { get; set; } 
    public int Value { get; set; } 
} 

e poi ho:

List<MyClass> myList = new List<MyClass>() 

// ... Populate myList 

if (myList.Contains("testType")) 
{ 
    // Do something 
} 

Nel codice di cui sopra, voglio myList.Contains() per abbinare sulla proprietà Type piuttosto che sul riferimento all'oggetto MyClass. Come ottengo questo? Si utilizza l'interfaccia IComparable o ICompare, si esegue l'override di MyClass.Equals() oppure è sufficiente ignorare il cast di stringa di MyClass?

Edit: Dopo aver fatto alcuni test con l'override Equals() e il cast serie di MyClass, attuazione e ICompareIComparable, ho scoperto che nessuno di questi metodi funziona. In realtà, sembra che quello che potrebbe funzionare è se dovessi scavalcare il cast di stringa MyClass, qualcosa come myList.Contains((MyClass)"testType"). Tuttavia penso che mi piace la risposta di Lo Scrum Meister meglio :)

risposta

9

È possibile utilizzare il metodo Any estensione:

if (myList.Any(x => x.Type == "testType")) 
{ 
    // Do something 
} 
+0

hhmmm ... sicuramente più semplice che la mia;) – IAbstract

+0

P.S. assicurati di aggiungere l'utilizzo di System.Linq; all'inizio del file .cs - questo mi ha fatto inciampare alcune volte :-) –

+0

Molto elegante. Questo sta sicuramente andando nella mia libreria di frammenti di codice. Realmente mi sono reso conto dopo aver postato la domanda che le mie stringhe di tipo devono essere uniche nel mio elenco, quindi ho finito per usare un 'Dictionary '. – Ozzah

0

Se si implementa IEquatable<T>, viene fondamentalmente l'override del metodo Object.Equals(). Secondo MSDN, è necessario sovrascrivere esplicitamente il metodo Object.Equals. È quindi possibile fare qualcosa di simile:

void Add (MyClass testCls) 
{ 
    var myCls = myList.Where(x => x.Equals(testCls)).Select(x => x).FirstOrDefault(); 

    if (myCls == null) 
    { 
      // then myList does not contain the object you want to add 
      myList.Add(testCls); 
    } 
} 

Per ulteriori informazioni su IEquatable<T>: MSDN IEquatable(T)
Il vantaggio di questo è che in realtà si sta verificando la Type proprietà di altri contenuti della lista - se questo è quello che stai cercando di fare .

0

Per chiarire la risposta di The Scrum Meister, la condizione che hai fornito non verrà nemmeno compilata, se la sto leggendo correttamente. Stai vedendo se una lista composta da oggetti MyClass contiene una stringa, quindi non funzionerà.

Sembra che ciò che si vuole veramente fare sia controllare e vedere se qualsiasi istanza di un oggetto MyClass presente in quell'elenco ha una proprietà Type che corrisponde al tipo desiderato.

Per amor di chiarezza, però, mi piacerebbe ridefinire la classe MyClass in questo modo:

public class MyClass { 
    public Type MyType { get; set; } 
    public int Value { get; set; } 
} 

Poi la sua condizione sarebbe:

if(myList.Any(x => x.MyType == typeof(SomeClass)) { // put the real class name in the typeof() 
    // Do something 
} 

speranza che spiega le cose un po 'più chiare.

+0

Il mio "Tipo" non è un tipo C# ...è un tipo di dipendente che sto leggendo da un CSV, ad esempio "Retail", "Supporto" o "Account". Non so se questo faccia qualche differenza per il tuo suggerimento? – Ozzah

+0

Ah, capisco. Preferisco solo la leggibilità della conversione del tipo. Se hai bisogno di ottenere un tipo da una stringa, puoi usare 'Type t = Type.GetType (String typename)' –

3

In aggiunta alla risposta del @The Scrum Meister, se si utilizza C# 2.0 è possibile utilizzare List<T>.Find

MyClass target = myList.Find(m => m.Type == "testType"); 
if (target != null) 
{ 
    // Do something to the target 
} 
Problemi correlati