Frage
Ich brauche Hilfe dieser Methode generisch zu machen. Es ist etwa zehnmal wiederholt Listen für verschiedene Web-Liste Kontrollen zu bekommen ( „MyType“ für die Art in der jeweiligen Steuerung verwendet Substitution).
private static IList<MyType> GetList(RequestForm form)
{
// get base list
IMyTypeRepository myTypeRepository = new MyTypeRepository(new HybridSessionBuilder());
IList<MyType> myTypes = myTypeRepository.GetAll();
// create results list
IList<MyType> result = new List<MyType>();
// iterate for active + used list items
foreach (MyType myType in myTypes)
{
if (myType.Active || form.SolutionType.Contains(myType.Value))
{
result.Add(myType);
}
}
// return sorted results
result.OrderBy(o => o.DisplayOrder);
return result;
}
Lassen Sie mich wissen, ob dies nicht genug Informationen. Ich denke, diese erweiterte Sprachfunktionen erfordern, dass ich nur mit Kennenlernen. Vielleicht sollte ich machen sie alle das gleiche Repository verwenden?
Danke für Ihre Hilfe.
EDIT: Danke für Ihre Hilfe. Ich habe keine Peer-Unterstützung, so dass dieses Board ist fantastisch und ich lernte etwas von jedem von euch. Ich wünschte, ich könnte alle Antworten akzeptieren.
Lösung
Sie können zunächst Ihre Funktion etwas lapidar wie folgt vor:
private static IList<MyType> GetList(RequestForm form)
{
// get base list
IMyTypeRepository myTypeRepository =
new MyTypeRepository(new HybridSessionBuilder());
IList<MyType> myTypes = myTypeRepository.GetAll();
return myTypes.Where(x => x.Active || form.SolutionType.Contains(x.Value))
.OrderBy(x => x.DisplayOrder).ToList();
}
An diesem Punkt wird der größte Teil des Inhalts der Funktion direkt an MyType
bezogen, so wie Sie weiter verbessern kann es hängt davon ab, wie MyType
bezieht sich auf die anderen Typen beteiligt. Zum Beispiel, hier ist eine hypothetische Version, die Sie schreiben könnten, wenn Ihre andere Arten einen vernünftigen schau (für mich) Vertrag folgen:
private static IList<T> GetList(RequestForm form) where T : OrderedValueContainer
{
// we'll want to somehow genericize the idea of a TypeRepository that can
// produce these types; if that can't be done, we're probably better off
// passing a repository into this function rather than creating it here
var repository = new TypeRepository<T>(new HybridSessionBuilder());
IList<T> myTypes = repository.GetAll();
// the hypothetical OrderedValueContainer class/interface
// contains definitions for Active, Value, and DisplayOrder
return myTypes.Where(x => x.Active || form.SolutionType.Contains(x.Value))
.OrderBy(x => x.DisplayOrder).ToList();
}
Andere Tipps
Wenn alle Typen die gleiche Schnittstelle implementieren, (wenn sie nicht dann sie machen, und stellen Sie sicher, dass alle Eigenschaften mit der Schnittstelle hinzuzufügen, die in diesem Verfahren benötigt werden), dann können Sie etwas tun:
private static IList<T> GetList(RequestForm form)
where T: IMyInterface
{
// get base list
IMyTypeRepository myTypeRepository = new MyTypeRepository(new HybridSessionBuilder());
IList<T> myTypes = myTypeRepository.GetAll();
// create results list
IList<T> result = new List<T>();
// iterate for active + used list items
foreach (T myType in myTypes)
{
if (myType.Active || form.SolutionType.Contains(myType.Value))
{
result.Add(myType);
}
}
// return sorted results
return result.OrderBy(o => o.DisplayOrder).ToList();
}
Eine weitere Änderung, die ich gemacht ist die letzte Zeile, wo Sie die orderby auf einer separaten Linie hatten und eigentlich nie die geordnete Liste zu erfassen.
EDIT: das Repository Problem zu lösen, können Sie ein Repository Fabrik der Art, die die richtige Repository auf die Art der T basierend zurückgibt:
public static IMyTypeRepository GetRepository(Type t)
{
if(t == typeof(Type1))
{
return Type1Repository();
}
if(t == typeof(Type2))
{
return Type2Repository();
}
.......
}
natürlich davon aus, dass alle Ihre Repositories die IMyRepository-Schnittstelle implementieren.
Zunächst einmal alle Typen müssen eine gemeinsame interface
implementieren, die Eigenschaften wie Active
definieren, Value
...
Auch für das, was ich sagen kann, es muss unabhängig von der MyType
ein Repository-Schnittstelle für alle Repositories, so dass Sie eine generische Methode wie folgt verwenden können. Die GetAll()
Methode sollte in der IRepository
definiert werden.
public interface IRepository<T> where T : IMyType
{
IList<T> GetAll();
}
public class RepositoryFactory
{
public static IRepository<T> createRepository<T>(ISessionBuilder sb) where T : IMyType
{
// create repository
}
}
public interface IMyType
{
bool Active { get; }
string Value { get; }
}
private static IList<T> GetList(RequestForm form) where T : IMyType
{
// get base list
IRepository<T> repository = RepositoryFactory.createRepository<T>(new HybridSessionBuilder());
IList<T> myTypes = repository.GetAll();
// create results list
IList<T> result = new List<T>();
// iterate for active + used list items
foreach (T myType in myTypes)
{
if (myType.Active || form.SolutionType.Contains(myType.Value))
{
result.Add(myType);
}
}
// return sorted results
return result.OrderBy(o => o.DisplayOrder).ToList();
}
Unter der Annahme, dass die Verwahrungs eine gemeinsame Schnittstelle zu teilen, sollte das Problem mit dem Repository leicht zu beheben: Fügen Sie eine statische Funktion wie
public static IRepository RepositoryForType(Type t)
{
if(t == typeof(SomeClass))
return new SomeClassRepository(new HybridSession());
else if ...
else throw new InvalidOperationException("No repository for type " + t.Name);
}
Das sollten Sie die geringste Menge an Änderungen an Ihrem vorhandenen Code benötigen, sondern daran, dass Sie in der Zukunft werden Klassen Unterstützung in dieser Funktion für neue Repositories hinzufügen, wie Sie neue Repositories in Ihrem Projekt hinzufügen (wenn Sie Unit-Tests unter Verwendung finden Sie leicht ausrechnen, wenn Sie diesen Helfer vergessen sowieso).