9 Stimmen

C# Zugriff auf die Eigenschaften eines generischen Objekts

Ich habe eine Methode, die die Anzahl der Kontakte zählt, die jeder Lieferant, Kunde und Hersteller hat (dies ist ein Szenario, um das Erklären zu erleichtern!)

Die Modelle werden alle durch Linq to SQL-Klassen erstellt. Jeder Lieferant, Kunde und Hersteller kann einen oder mehrere Kontakte haben

public int CountContacts<TModel>(TModel entity) where TModel : class
{
    return entity.Contacts.Count();
}

Das obige funktioniert natürlich nicht, weil die "Entität" generisch ist und nicht weiß, ob sie die Eigenschaft "Kontakte" hat. Kann jemand helfen, wie man dies erreichen kann?

6voto

kemiller2002 Punkte 110605

Eine einfache Möglichkeit wäre es, eine Schnittstelle an die Klassen anzuhängen, die in der generischen Klasse implementiert werden.

public int CountContacts<TModel>(TModel entity) where TModel : IContacts

interface IContacts
{
   IList<Contact> Contacts {get;} //list,Ilist,ienumerable
}

3voto

bruno conde Punkte 47059

Eine Möglichkeit zur Durchsetzung einer Vertrag wo Lieferanten, Kunden und Hersteller eine Contacts Eigenschaft ist mit Schnittstellen. Jede Entität soll eine Schnittstelle implementieren, die die Contacts Eigentum:

interface IContactable
{
   IEnumerable<Contact> Contacts {get;}
}

public int CountContacts<TModel>(TModel entity) where TModel : class, IContactable
{
    return entity.Contacts.Count();
}

1voto

n8wrl Punkte 19091

Alle Antworten bisher sind richtig, aber sollte auch darauf hinweisen, dass der Grund, warum Ihr Code nicht kompilieren ist, weil die TModel-Typen nicht alles gemeinsam haben. Durch die Angabe einer gemeinsamen Basisklasse oder Schnittstelle, die sie alle mit Ihrer Eigenschaft "Contacts" implementieren, wird Ihr Code funktionieren.

0voto

Noel Punkte 2041

Eine andere Möglichkeit besteht darin, eine Schnittstelle nur für das Zählen zu schaffen. Sie können sie ICountable nennen.

Von MSDN

public interface ICountable<out T>  
{
    int Count{ get; }
}
public class MyCollection : ICountable<string>, ICountable<FileStream>
{  
    int ICountable<string>.Count
    {
        get { return 1; }
    }
    int ICountable<FileStream>.Count
    {
        get { return 2; }
    }
}

0voto

Venemo Punkte 17747

Es gibt mehrere Lösungen für dieses Problem.

  • Vererben Sie die gleiche abstrakte Klasse oder implementieren Sie die gleiche Schnittstelle mit den Entitäten. (Die anderen haben damit jede mögliche Lösung ausgeschöpft.)
  • Wenn Sie .NET 4 verwenden, wird die dynamic Stichwort kann die billigste Lösung sein.

Zum Beispiel:

public int CountContacts(dynamic entity)
{
    return entity.Contacts.Count();
}

Dies bedeutet, dass entity wird erst zur Laufzeit ausgewertet, und wenn Sie die Methode zufällig für ein Objekt aufrufen, das keine Contacts Eigenschaft, wird eine Ausnahme ausgelöst.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X