Frage

First off, ich verstehe die Gründe, warum eine Schnittstelle oder abstrakte Klasse (in der .NET/C# - Terminologie) kann nicht über abstrakte statische Methoden.Meine Frage ist dann der Schwerpunkt mehr auf die besten design-Lösung.

Was ich möchte, ist eine Reihe von "Helfer" - Klassen, die alle Ihre eigene statische Methoden, so dass, wenn ich die Objekte A, B und C von einem Drittanbieter, die ich haben kann-helper-Klassen mit Methoden wie

AHelper.RetrieveByID(string id);
AHelper.RetrieveByName(string name);
AHelper.DumpToDatabase();

Da mein AHelper, BHelper, und CHelper Klassen werden im Grunde alle die gleichen Methoden, scheint es sinnvoll, diese Methoden zu einer Schnittstelle, die diese Klassen leiten Sie aus.Allerdings wollen diese Methoden statisch zu sein schließt mich aus, die eine generische Schnittstelle oder abstrakte Klasse für alle von Ihnen abzuleiten.

Ich könnte immer machen Sie diese Methoden nicht statisch und dann instanziieren Sie die Objekte zuerst wie

AHelper a = new AHelper();
a.DumpToDatabase();

Aber dieser code scheint nicht intuitiv zu mir.Was sind Ihre Vorschläge?Sollte ich aufgeben, die über eine Schnittstelle oder abstrakte Klasse insgesamt (die situation, die ich bin in jetzt) oder können diese möglicherweise umgestaltet werden, um zu erreichen, das design, die ich Suche?

War es hilfreich?

Lösung

Suche in Ihre Antwort Ich denke an die folgenden Zeilen:

  • Sie könnte gerade haben eine statische Methode, die einen parameter vom Typ und führt die erwartete Logik basierend auf dem Typ.
  • Sie können eine virtuelle Methode in der abstrakten Basis, wo Sie die SQL in der konkreten Klasse.So, die enthält alle die gemeinsame code, der erforderlich ist, von beiden (z.B.exectuting die Befehls-und zurückgeben des Objekts) während der Verkapselung von "Spezialisten" bit (z.B.die SQL) in der sub-Klassen.

Ich bevorzuge die zweite option, obwohl Ihr natürlich auf Sie.Wenn Sie mich brauchen, um weiter ins detail gehen, lassen Sie es mich bitte wissen und ich werde glücklich sein, Sie zu Bearbeiten/aktualisieren :)

Andere Tipps

Wenn ich du wäre würde ich versuchen zu vermeiden jede Statik.IMHO ich habe immer am Ende mit irgendeiner Art von Problemen bei der Synchronisierung auf der Straße mit Statik.Das sagte Sie präsentieren ein klassisches Beispiel für die generische Programmierung mit templates.Ich übernehmen die template-basierte Lösung von Rob Kupfer vorgestellt, die in einem der Beiträge weiter oben.

Für eine generische Lösung zu Ihrem Beispiel, Sie können dies tun:

public static T RetrieveByID<T>(string ID)
{
     var fieldNames = getFieldNamesBasedOnType(typeof(T));
     QueryResult qr = webservice.query("SELECT "+fieldNames + " FROM "
                                     + tyepof(T).Name
                                     +" WHERE Id = '" + ID + "'");
     return (T) qr.records[0];
}

Ich persönlich würde vielleicht die Frage, warum die Typen müssen eine statische Methode, bevor Sie sogar denken weiter..

Warum nicht mal ein Dienstprogramm Klasse mit statischen Methoden, die Sie brauchen, um zu teilen?(z.B. ClassHelper.RetrieveByID(string id) oder ClassHelper<ClassA>.RetrieveByID(string id)

In meiner Erfahrung mit dieser Art von "Straßensperren" das problem ist nicht die Einschränkungen der Sprache, sondern auch die Einschränkungen von meinem design..

Wie sind ObjectA und AHelper verwandt?Ist AHelper.RetrieveByID() der gleichen Logik wie BHelper.RetrieveByID()

Wenn ja, wie wäre es mit einer Utility-Klasse basierenden Ansatz (Klasse mit öffentlichen statischen Methoden nur und kein Staat)

static [return type] Helper.RetrieveByID(ObjectX x) 

Sie können nicht überlastung Methoden durch Variation nur die Rückkehr geben.

Sie können verschiedene Namen:

static AObject GetAObject(string id);
static BObject GetBObject(string id);

Oder Sie können eine Klasse erstellen mit casting Betreiber:

class AOrBObject
{ 
   string id;
   AOrBObject(string id) {this.id = id;}

   static public AOrBObject RetrieveByID(string id)
   {
        return new AOrBObject(id);
   }

   public static AObject explicit operator(AOrBObject ab) 
    { 
        return AObjectQuery(ab.id);
    }

   public static BObject explicit operator(AOrBObject ab)
    { 
        return BObjectQuery(ab.id);
    } 
}

Dann Sie können es nennen, wie so:

 var a = (AObject) AOrBObject.RetrieveByID(5);
 var b = (BObject) AOrBObject.RetrieveByID(5); 

In C# 3.0, statische Methoden können verwendet werden auf Schnittstellen, als wären Sie ein Teil davon durch die Verwendung von erweiterungsmethoden, wie mit DumpToDatabase() unten:

static class HelperMethods
 {  //IHelper h = new HeleperA();
    //h.DumpToDatabase() 
    public static void DumpToDatabase(this IHelper helper) { /* ... */ }

    //IHelper h = a.RetrieveByID(5)
    public static IHelper RetrieveByID(this ObjectA a, int id) 
     { 
          return new HelperA(a.GetByID(id));
     }

    //Ihelper h = b.RetrieveByID(5)       
    public static IHelper RetrieveByID(this ObjectB b, int id)
     { 
          return new HelperB(b.GetById(id.ToString())); 
     }
 }

Wie Schreibe ich feedback auf Stack Overflow?Edit my original post oder post eine "Antwort"?Sowieso, ich dachte, es könnte helfen, ein Beispiel zu geben, was Los ist auf in AHelper.RetrieveByID() und BHelper.RetreiveByID()

Im Grunde, beide Methoden gehen gegen einen Dritten webservice, der gibt verschiedene einer generische (Gießmasse) - Objekt unter Verwendung einer Abfrage-Methode, die in pseudo-SQL-Zeichenfolge als Parameter.

So, AHelper.RetrieveByID(string ID) Aussehen könnte

public static AObject RetrieveByID(string ID)
{
  QueryResult qr = webservice.query("SELECT Id,Name FROM AObject WHERE Id = '" + ID + "'");

  return (AObject)qr.records[0];
}

public static BObject RetrieveByID(string ID)
{
  QueryResult qr = webservice.query("SELECT Id,Name,Company FROM BObject WHERE Id = '" + ID + "'");

  return (BObject)qr.records[0];
}

Hoffentlich das hilft.Wie Sie sehen können, die zwei Methoden sind ähnlich, aber die Abfrage kann sehr etwas anders aufgrund der verschiedenen Objekt-Typ zurückgegeben wird.

Oh, und Rob, bin ich vollkommen einverstanden-das ist mehr als wahrscheinlich, eine Einschränkung meiner design-und nicht die Sprache.:)

Sind Sie auf der Suche nach polymorphen Verhalten?Dann werden Sie wollen die Schnittstelle und der normale Konstruktor.Was ist unintuitiv, über den Aufruf eines Konstruktors?Wenn Sie nicht brauchen Polymorphismus (klingt wie Sie nicht verwenden es jetzt), dann kann man den Stock mit dem statischen Methoden.Wenn diese sind Wrapper um einen vendor-Komponente, dann vielleicht könnten Sie versuchen, verwenden Sie eine factory-Methode zum erstellen Ihnen gerne VendorBuilder.GetVendorThing("A"), die ein Objekt zurückgeben, Typ IVendorWrapper.

marxidad Nur eine schnelle Punkt zu beachten, Justin hat bereits gesagt, dass die SQL variiert stark, abhängig von der Art, so dass ich gearbeitet habe, auf der Grundlage, dass es könnte etwas sein komplett anders abhängig von der Art, daher delegieren Sie es an die Unterklassen in Frage.In der Erwägung, dass Ihre Lösung Paare SQL SEHR eng an die Art (D. H.es ist die SQL).

rptony Guter Punkt auf die möglichen sync-Probleme mit der Statik, eine, die ich nicht erwähnt, also danke dir Auch :) die, seine Rob Cooper (nicht Kupfer) BTW ;) :D ( EDIT: Dachte nur, ich würde erwähnen, dass in Fall es nicht ein Tippfehler, ich erwarte, dass es ist, also kein problem!)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top