Antwort
Bearbeiten: Bitte beachten Sie, dass diese Antwort gegeben wurde, bevor die Frage in einer Bearbeitung komplett geändert wurde. Aus diesem Grund bezieht es sich jetzt auf Dinge, die nur in der ursprünglich angegebenen Frage vorhanden waren. Ich bitte um Entschuldigung für all die "dangling pointers". :-)
Kurze Antwort:
Mit dem Code, den Sie geschrieben haben, sehe ich nicht, eine Alternative zu IFoo<T>
zu werfen. Wenn Sie dies nicht tun, gibt der Compiler eine Warnung aus (zumindest auf meinem Rechner).
Kompliziertere Antwort:
Gibt es in Ihrem Code haben, um tatsächlich so sein? Genauer gesagt, brauchst du den fraglichen Gips überhaupt?
Ich nehme an, Sie werden Ihre Factory-Methode mehr oder weniger so nennen:
var stringFoo = FooFactory.CreateFoo<string>();
Sie haben die Template-Parameter (string
in diesem Fall), um ausdrücklich, weil es nicht von jedem Verfahren Argumente abgeleitet werden kann (in diesem Fall, weil es überhaupt keine gibt). Offensichtlich gibt die Factory-Methode eine IFoo<string>
zurück.
Nun, da Sie explizit müssen die Art zur Laufzeit angeben, könnte man genauso gut schreiben:
var stringFoo = StringFoo.Create();
und hat daher eine Factory-Methode innerhalb StringFoo
, wie dies, dass bedingungslos die offensichtlich tut :
public class StringFoo : IFoo<string>
{
...
public static StringFoo Create() // or alternatively, return an IFoo<string>
{
return new StringFoo();
}
}
dieses Muster zu anderen IFoo<T>
Implementierungen zu Durch die Anwendung dieses Sie die if
Kette oder switch
Block innerhalb FooFactory.CreateFoo<T>
speichern, stellen Sie Ihren Code einfacher, und loswerden der Notwendigkeit zu werfen (worüber Sie besorgt sind).
Verstehen Sie mich nicht falsch, ich bin mir bewusst, dass Factory-Methoden, die mehr als einen Objekttyp unterstützen, in einigen Fällen nützlich sind; aber es scheint in deinem Fall mehr Ärger zu verursachen, als es wert ist.
P. S .: Sie könnten ein Aspekt von einigen IoC Container interessant finden.Sie müssen normalerweise konfiguriert werden, und dies umfasst einen Prozess, bei dem Sie konkrete Typen (d. H. Implementierungsklassen) für abstrakte Schnittstellen registrieren. zum Beispiel (hier mit Autofac):
var builder = new ContainerBuilder();
builder.RegisterType<StringFoo>().As<IFoo<string>>();
später Dann können Sie eine Objektinstanz einer abstrakten Art anfordern:
using (var container = builder.Build())
{
var stringFoo = container.Resolve<IFoo<string>>();
...
}
Die Resolve
Methode ist der interessante Teil. Sie geben es mit einem abstrakten Typ an und unter Verwendung der registrierten Typen wird ein konkretes Objekt vom Typ StringFoo
zurückgegeben. Schau hinein, wenn es sich für dich nicht nach Overkill anhört! so etwas wie dieses :-)
Können Sie das Problem, das Sie mit diesem Mechanismus wird die Lösung beschreiben? Es gibt höchstwahrscheinlich einen klareren Weg, sich dem zu nähern.
bearbeiten
Und ja, riecht der Code. Sie haben den Raum für einen beliebigen Typ offen gelassen, außer Sie beschränken ihn dann auf einen einzelnen Typ und generieren eine Laufzeitausnahme. Warum haben Sie in diesem Fall einen Typparameter?
Nein, bin ich nicht. Ich verstehe nicht die Nützlichkeit einer abstrakten Fabrik, die eine generische Schnittstelle bereitstellt, aber letztendlich nur einen bestimmten konkreten Typ erzeugt. Was Sie beschrieben haben, ist eine Lösung für ein Problem, das Sie noch nicht beschrieben haben. Sagen Sie uns, was dieses * Problem * ist, anstatt Ihrer vorgefassten Meinung, wie Sie es lösen können, und wir werden Ihnen besser helfen können. –
Technologie im Vakuum führt oft zu Lösungen auf der Suche nach einem Problem. Ohne die Situationen zu definieren, die mit diesem Mechanismus behandelt werden, haben Sie keine Kriterien, anhand derer Sie ein Werturteil abgeben können. Wenn Ihre Frage mehr wäre, um festzustellen, ob dieser Ansatz eine praktikable Lösung für ein * Problem * ist, ist das anders. Ich persönlich sehe keine Verwendung für eine generische Fabrik, die nicht generisch ist und Laufzeitfehler verursacht, wenn sie als solche verwendet wird. Es ist, als würde man ein Auto bauen, das erst startet, wenn man in den Supermarkt geht. –
Sie könnten versuchen, ...
public static class FooFactory
{
private static readonly Dictionary<Type, Type> FooTypesLookup;
static FooFactory()
{
FooTypesLookup = (from type in typeof(FooFactory).Assembly.GetExportedTypes()
let fooInterface =
type.GetInterfaces().FirstOrDefault(
x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IFoo<>))
where fooInterface != null
let firstTypeArgument = fooInterface.GetGenericArguments().First()
select new { Type = type, TypeArgument = firstTypeArgument })
.ToDictionary(x => x.TypeArgument, x => x.Type);
}
public static IFoo<T> CreateFoo<T>()
{
var genericArgumentType = typeof(T);
Type closedFooType;
return FooTypesLookup.TryGetValue(genericArgumentType, out closedFooType)
? (IFoo<T>) Activator.CreateInstance(closedFooType)
: null;
}
}
Oder noch besser vorstellen Ihre Lieblings IoC-Container (Windsor, Strukturkarte, etc.) und alle Arten registrieren, die IFoo dort implementieren und dann lösen Sie sie bei Bedarf anstelle des Activator.CreateInstance-Aufrufs auf.
Das Ziel für mich war, Activator.CreateInstance() nicht zu verwenden. – Merritt
- 1. Ist das ein bekanntes Designmuster? Was ist sein Name?
- 2. Element ‚ToolkitScriptManager‘ ist kein bekanntes Element
- 3. ASP.NET: Element ist kein bekanntes Element
- 4. Ist dies ein Singleton-Muster?
- 5. Ist Repository-Muster ein Overkill
- 6. Ist die Funktionsparameterüberprüfung mit Fehlern ein gutes Muster in Go?
- 7. Ist VirtualHost ein gutes Muster in RabbitMQ?
- 8. Gibt es ein bekanntes gutes Tutorial über Cyclic Redundancy Check?
- 9. Ist dieses AJAX-Muster ein Speicherleck?
- 10. ist dies ein Decorator-Muster (PHP)?
- 11. Was ist das für ein Muster?
- 12. Java Regex String Parse, ist ein Muster
- 13. `autodetect ': Kein bekanntes ORM wurde erkannt
- 14. Gibt es ein bekanntes Paradigma für die Iteration von Enum-Werten?
- 15. Liste nur Verzeichnisse Namen, die ein Muster
- 16. Regex Übereinstimmung für ein bestimmtes Muster ohne ein spezifisches Muster
- 17. Regex ein spezifisches Muster
- 18. Gibt es ein Muster oder ein Juwel zum Speichern von Optionen in einer serialisierten Spalte
- 19. Finden Sie die erste Datei, die ein Muster mit PowerShell
- 20. ein Muster von '*' drucken
- 21. Finde Teilstrings, die in ein bestimmtes Muster eingebettet sind
- 22. Best Practice: Generieren und Analysieren von Netzwerkpaketen für ein bekanntes Protokoll in C#?
- 23. Wie ein Strich Muster
- 24. Was ist das Muster für die vollständige Eingabe in Logstash?
- 25. So verwenden Sie sed, um ein Muster in einer Datei nur in Zeilen zu ersetzen, die ein anderes Muster enthalten
- 26. wie JQuery-Selektor (Ex-ID) und ein bekanntes DOM-Objekt in einzelner Abfrage
- 27. Was ist ein gutes JavaScript-Muster für die Kategorisierung von Dingen in Typen?
- 28. Was ist ein gutes Muster für die Implementierung der Zugriffskontrolle in einem GraphQL-Server?
- 29. Ein Muster in der Zeichenkette finden
- 30. Bereinigen Sie die Muster?
Ich würde einen Schalter anstelle einer if-Kette in der 'CreateFoo()' Methode verwenden. –
ANeves