15. september 2011 - 09:41Der er
8 kommentarer og 1 løsning
Interface: Kræv at en metodes parameter er samme type som klassen
Jeg vil gerne lave et interface, indeholdende en metode som kan kopiere indholdet af parametret til klassen. Det kræver selvfølgelig at parametret er af samme type som selve klassen
public interface ICopyAble { T CopyFrom<T>(T inputItem); }
Alternativt ... alt efter hvordan du synes det er pænæst.
public interface ICopyAble<T> { T CopyFrom(T inputItem); }
Som så vil komme til at se sådan her ud: public class MyClass : ICopyAble<string> { public string CopyFrom(string inputItem) { throw new System.NotImplementedException(); } }
heinzdmx: ICloneable.Clone retunerer et nyt objekt. Det jeg ønsker er at kopiere data ind i et eksisterende objekt.
buzzzz: Det kan man selvfølgelig gøre, men det jeg vil er:
MyClass c1 = new MyClass (); MyClass c2 = new MyClass ();
...
c1.CopyFrom (c2) ;
...
På din måde skal man angive klassen i definitionen af klassen: public class MyClass : ICopyAble<MyClass>
og kan dermed angive en forkert: public class MyClass : ICopyAble<MyClass2>
Min ide var at Interfacet skulle kræve at parametret var samme type som klassen (som her - hvis det havde virket): interface ICopyAble<T> where T : typeof(this) { void CopyFrom(T Source ); }
Jeg tror godt jeg forstår dit problem. Og der er ikke en constraint på generics du kan bruge. Men jeg tror faktisk at din tilgang til det er lidt bagvendt.
Hvis du alligevel vil have at metoden skal "overskrive" din eksisterende instans, hvorfor så ikke lade den returnere den i stedet?
MyClass c1 = new MyClass(); [...]
MyClass c2 = c1.Copy();
Dermed undgår du også, at du kan skrive en "forkert" type i din generic.
skelboe: Du har ret i at man kan gøre det du angiver, men det vil give en fejl ved runtime, hvis man kalder den med et forkert objekt. Det jeg ønsker er at interfacet kræver at typen man kalder objektet med er det samme som objektet.
bvli: Det jeg ønsker er at overskrive data. Mit c1 har nogle events, som andre objekter abonerer på. Så kommer der et nyt objekt (c2 )som indeholder nye data. Dem vil jeg gerne have have over i c1, som så samtidig raiser et event om at der er nye data. Den information skal så komme til de objekter, som abonerer på c1.
Alt det er ikke svært at lave, men jeg ønsker at lave et interface, som kræver dette, således at jeg bare kan implementere ICopyable, og så er jeg sikker på at klassen er korrekt
Hvis man endelig kunne, så tror jeg også at .NET selv ville have valgt at gøre det med: IEqualityComparer<string>, IEquatable<>, og mange flere ...
Men hvis du alligevel skal huske at implementere et interface ... for at bruge en method og ikke selv interfacet er der så ikke noget galt i din akitektur?
Som jeg har kunnet google mig til, har java noget der hedder "self bounding generics" som måske er det du leder efter. Blev ikke helt klog på det ... da de også snakkede om Scala.
Generics handler i min verden om at behandle ting på samme måde.
Du vil reelt bare her have en metode på din klasse som hedder "Copy" som bare tager et item. Er det ikke ligeså nemt at implementere og huske at gøre det hvis der alligevel ikke bliver brugt generics ?
Det eneste du kan er en smide en masse constraints på dit interface eller.
Eventuelt kan du kigge på PostSharp som kan lave en masse compile time check om klasser der implementere interface I har en metoder der hedder copy som tager en parameter af sig selv.
public interface ICopyable<T> { void CopyFrom(T Source); }
Jeg ville gerne have lavet en begrænsning på T, som sagde at den skulle være this (eller en klasse der arvede fra this), men konklusionen må være at det ikke (Umuddelbart) kan lade sig gøre.
Jeg lukker derfor spørgsmålet
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.