Statické metody v rozhraní / abstraktní třídy

hlasů
10

Za prvé, chápu důvody, proč rozhraní nebo abstraktní třída (v .NET C # terminologie /) nemohou mít abstraktní statické metody. Moje otázka je tedy více zaměřují na nejlepší konstrukční řešení.

To, co chci, je soubor „pomocných“ tříd, které všechny mají své vlastní statické metody tak, že když jsem si předmět, A, B a C od dodavatele třetí strany, mohu mít pomocné třídy s metodami, jako je

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

Vzhledem k tomu, moje tříd AHelper, BHelper a CHelper budou všichni v zásadě mít stejné metody, zdá se, že má smysl pro pohyb těchto metod rozhraní, které tyto třídy pak odvozují od. Nicméně, kteří chtějí tyto metody jako statické mi brání v mající obecný rozhraní nebo abstraktní třída pro všechny z nich odvodit z.

Mohl bych vždy provést tyto metody non-static a pak prvního, jako instanci objekty

AHelper a = nové AHelper ();
a.DumpToDatabase ();

Nicméně, toto číslo se nezdá být tak intuitivní, ke mně. Jaké jsou vaše návrhy? Měl jsem opustit pomocí rozhraní nebo abstraktní třídy dohromady (situace Jsem teď), nebo to může být případně refactored k dosažení konstrukci jsem hledal?

Položena 18/08/2008 v 14:42
zdroj uživatelem
V jiných jazycích...                            


10 odpovědí

hlasů
5

Kdybych byl vámi bych se snažit, aby se zabránilo statika. IMHO Vždycky jsem skončil s nějakým druhem problémů synchronizace po silnici se statikou. Jak již bylo řečeno, který prezentuje klasický příklad generického programování s využitím šablon. I přijme řešení založené šablony Rob mědi uvedenou v jednom z míst výše.

Odpovězeno 18/08/2008 v 15:30
zdroj uživatelem

hlasů
3

Pro obecné řešení pro váš příklad, můžete to udělat:

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];
}
Odpovězeno 18/08/2008 v 15:30
zdroj uživatelem

hlasů
3

Při pohledu na vaši odpověď Přemýšlím souladu s následujícími body:

  • Ty by mohly mít jen statickou metodu, která přebírá parametr typu a provádí očekávaný logiky založené na tomto typu.
  • Mohli byste vytvořit virtuální metodu v abstraktní základnu, kde zadáte SQL ve třídě betonu. Takže obsahuje všechny společný kodex, který je vyžadován jak (např exectuting příkaz a vrací objekt), zatímco zapouzdření „specializované“ bitů (např SQL) v dílčích kategorií.

Dávám přednost druhé možnosti, ačkoliv jeho samozřejmě na vás. Kdybys mě potřebovala jít do detailů, prosím dejte mi vědět a já budu rád, upravit / aktualizovat :)

Odpovězeno 18/08/2008 v 15:25
zdroj uživatelem

hlasů
2

Nelze přetížit metody změnou pouze návratový typ.

Můžete použít různá jména:

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

Nebo můžete vytvořit třídu s provozovateli odlévání:

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);
    } 
}

Pak můžete volat třeba takto:

 var a = (AObject) AOrBObject.RetrieveByID(5);
 var b = (BObject) AOrBObject.RetrieveByID(5); 
Odpovězeno 18/08/2008 v 15:18
zdroj uživatelem

hlasů
2

Jak se ObjectA a AHelper příbuzní? Je AHelper.RetrieveByID()stejná logika jakoBHelper.RetrieveByID()

Pokud ano, jak se o přiblížení Utility třídy rozhraní (třídy s pouze ve veřejných statických metod a ne stát)

static [return type] Helper.RetrieveByID(ObjectX x) 
Odpovězeno 18/08/2008 v 14:57
zdroj uživatelem

hlasů
2

Já osobně bych snad otázku, proč každý z typů musí mít statickou metodu ještě předtím, než přemýšlet dál ..

Proč ne vytvořit třídu utlity s statické metody, které potřebují sdílet? (např ClassHelper.RetrieveByID(string id)neboClassHelper<ClassA>.RetrieveByID(string id)

Podle mé zkušenosti s těmito jakési „překážek“ problém není omezení jazyka, ale omezení můj návrh ..

Odpovězeno 18/08/2008 v 14:53
zdroj uživatelem

hlasů
1

V C # 3.0, statické metody mohou být použity na rozhraní, jako by se jednalo o jejich část pomocí prodlužovacích metod, jak se DumpToDatabase () níže:

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())); 
     }
 }
Odpovězeno 18/08/2008 v 14:46
zdroj uživatelem

hlasů
0

marxidad Jen rychlý poznamenat, Justin již řekl, že SQL značně liší v závislosti na typu, takže jsem pracoval na základě toho, že by to mohlo být něco zcela odlišná v závislosti na typu, a proto, že jej přenesou do podtřídy dotčené , Zatímco vaše řešení párů SQL velmi těsně k typu (to znamená, že je SQL).

rptony Dobrý bod o možných problémech synchronizace se statikou, kterou jsem zapomněl zmínit, takže děkuji :) Také jeho Rob Cooper (ne Copper) BTW): D ( EDIT: Jen jsem chtěl uvést, že v případě, že nebylo‘ t překlep, myslím, že to je, takže žádný problém!)

Odpovězeno 18/08/2008 v 15:42
zdroj uživatelem

hlasů
0

Hledáte polymorfní chování? Pak budete chtít rozhraní a normální konstruktor. Co je unintuitive asi volá konstruktor? Pokud nepotřebujete polymorfismus (zní, jako byste ji nepoužíváte nyní), pak můžete držet se svými statickými metodami. Pokud se jedná o všechny obaly kolem komponenty dodavatele, pak možná můžete zkusit použít tovární metodu k jejich vytvoření jako VendorBuilder.GetVendorThing ( „A“), které by mohly vrátit objekt typu IVendorWrapper.

Odpovězeno 18/08/2008 v 15:07
zdroj uživatelem

hlasů
0

Jak vložím svůj názor na přetečení zásobníku? Upravit svůj původní příspěvek nebo příspěvek „odpověď“? Mimochodem, myslel jsem, že by mohlo pomoci uvést příklad toho, co se děje v AHelper.RetrieveByID () a BHelper.RetreiveByID ()

Zjednodušeně řečeno, obě tyto metody jdou nahoru proti webové služby třetí strany, která vrací různé obecný (slévatelného) objektu pomocí metody dotazu, který bere v pseudo-SQL řetězec jako jeho jediné parametry.

Takže AHelper.RetrieveByID (řetězec ID) by mohla vypadat

public static AObject RetrieveByID (řetězec ID)
{
  QueryResult qr = webservice.query ( "SELECT id, jméno FROM AObject where id = '" + ID + "'");

  výnos (AObject) qr.records [0];
}

public static BObject RetrieveByID (řetězec ID)
{
  QueryResult qr = webservice.query ( "SELECT id, jméno, firma z BObject where id = '" + ID + "'");

  výnos (BObject) qr.records [0];
}

Doufejme, že to pomohlo. Jak vidíte, obě metody jsou podobné, ale dotazu může být trochu liší v závislosti na jiný typ objektu, které se vracejí.

Oh, a Rob, naprosto souhlasím - to je více než pravděpodobné, omezení svém návrhu a ne jazyk. :)

Odpovězeno 18/08/2008 v 15:05
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more