RE: [Ikvm-developers] Ghosts and generics
Brought to you by:
jfrijters
From: Jonathan P. <jp...@ny...> - 2003-10-22 22:53:21
|
Jeroen, I'm sorry to keep answering my own emails, but I just realized that you can use explicit casts instead of calling the wrap method to convert strings to CharSequence args in method calls. What do you think of the updated example below: using System; using System.Text; public interface ICharSequence { int length(); char charAt(int index); CharSequence subSequence(int start, int end); string toString(); } public abstract class CharSequence : ICharSequence { public abstract int length(); public abstract char charAt(int index); public abstract CharSequence subSequence(int start, int end); public abstract string toString(); public static implicit operator string (CharSequence theCharSequence) { return theCharSequence.toString (); } public static explicit operator CharSequence (string theString) { return (new StringWrapper (theString)); } } internal class StringWrapper : CharSequence { private readonly string fStringData = ""; public StringWrapper (string itsStringData) { fStringData = itsStringData; } public override int length() { return (CharSequenceHelper.length (fStringData)); } public override char charAt(int index) { return (CharSequenceHelper.charAt (fStringData, index)); } public override CharSequence subSequence(int start, int end) { return (CharSequenceHelper.subSequence (fStringData, start, end)); } public override string toString () { return (fStringData); } } public class CharSequenceHelper { public static CharSequence Wrap (string theString) { return (new StringWrapper (theString)); } public static int length (string theCharSequence) { return (theCharSequence.Length); } public static char charAt (string theCharSequence, int index) { return (theCharSequence [index]); } public static CharSequence subSequence (string theCharSequence, int start, int end) { return (CharSequenceHelper.Wrap (theCharSequence.Substring (start, end))); } public static string toString (string theCharSequence) { return (theCharSequence); } public static int length (CharSequence theCharSequence) { return (theCharSequence.length ()); } public static char charAt (CharSequence theCharSequence, int index) { return (theCharSequence.charAt (index)); } public static CharSequence subSequence (CharSequence theCharSequence, int start, int end) { return (theCharSequence.subSequence (start, end)); } public static string toString (CharSequence theCharSequence) { return (theCharSequence.toString ()); } } public class GenericCharSequenceTest { static CharSequence reverseCharSequence(CharSequence s) { StringBuilder theStringBuilder = new StringBuilder (); for (int i = s.length () - 1; i >= 0; i--) { theStringBuilder.Append (s.charAt (i)); } return (CharSequenceHelper.Wrap (theStringBuilder.ToString ())); } static void Main(string[] args) { string theTestString = "abc"; char theFirstChar = CharSequenceHelper.charAt (theTestString, 0); Console.WriteLine (theFirstChar); CharSequence theCharSequence = CharSequenceHelper.Wrap (theTestString); theFirstChar = CharSequenceHelper.charAt (theCharSequence, 0); Console.WriteLine (theFirstChar); CharSequence theReverseCharSequence = reverseCharSequence (theCharSequence); Console.WriteLine (theReverseCharSequence.toString ()); theReverseCharSequence = reverseCharSequence ((CharSequence) theTestString); Console.WriteLine (theReverseCharSequence.toString ()); } } -Jonathan -----Original Message----- From: Jonathan Pierce [mailto:jp...@ny...] Sent: Wednesday, October 22, 2003 4:43 AM To: 'Jonathan Pierce'; 'Jeroen Frijters' Cc: ikv...@li... Subject: RE: [Ikvm-developers] Ghosts and generics Jeroen, I know we've probably discussed this before, but my head's not that clear today. Why can't you just use overloading on static methods to implement ghost interfaces instead of converting instances to a common type? You could just remap the calls to the interface methods to calls on the helper class static methods. I don't think you need to be able to cast a string to a CharSequence as long as CharSequenceHelper implements methods for both. Am I missing something here? using System; public interface CharSequence { int length(); char charAt(int index); CharSequence subSequence(int start, int end); string toString(); } public class StringWrapper : CharSequence { private readonly string fStringData = ""; public StringWrapper (string itsStringData) { fStringData = itsStringData; } public int length() { return (CharSequenceHelper.length (fStringData)); } public char charAt(int index) { return (CharSequenceHelper.charAt (fStringData, index)); } public CharSequence subSequence(int start, int end) { return (CharSequenceHelper.subSequence (fStringData, start, end)); } public string toString () { return (fStringData); } } public class CharSequenceHelper { public static int length (string theCharSequence) { return (theCharSequence.Length); } public static char charAt (string theCharSequence, int index) { return (theCharSequence [index]); } public static CharSequence subSequence (string theCharSequence, int start, int end) { return (new StringWrapper (theCharSequence.Substring (start, end))); } public static string toString (string theCharSequence) { return (theCharSequence); } public static int length (CharSequence theCharSequence) { return (theCharSequence.length ()); } public static char charAt (CharSequence theCharSequence, int index) { return (theCharSequence.charAt (index)); } public static CharSequence subSequence (CharSequence theCharSequence, int start, int end) { return (theCharSequence.subSequence (start, end)); } public static string toString (CharSequence theCharSequence) { return (theCharSequence.toString ()); } } public class GenericCharSequenceTest { static void Main(string[] args) { string theTestString = "abc"; char theFirstChar = CharSequenceHelper.charAt (theTestString, 0); Console.WriteLine (theFirstChar); StringWrapper theStringWrapper = new StringWrapper (theTestString); theFirstChar = CharSequenceHelper.charAt (theStringWrapper, 0); Console.WriteLine (theFirstChar); } } -----Original Message----- From: Jonathan Pierce [mailto:jp...@ny...] Sent: Wednesday, October 22, 2003 12:28 AM To: 'Jeroen Frijters' Cc: 'ikv...@li...' Subject: RE: [Ikvm-developers] Ghosts and generics Jeroen, The overloading is just an idea to let you make the call in a generic way. Using generics allows you to pass around parameters in a type safe way to methods that implement the interface and use delegates to call the correct implementation method. public static char charAt<T>(T theCharSequence, CharSequence_charAt<T> theDelegate, int i) { return (theDelegate (theCharSequence, i)); } >> what do you think of my new value type approach? I like it. It seems like it will work well aside from the array issue. I don't remember what your final enum implementation is, but does make sense to do something similar for them so they are also wrapped as ValueTypes? Does it make sense to rename things so the interface name is CharSequence and implementing classes can use the CharSequence name? public interface CharSequence { char charAt(int i); // ... other methods ... } public struct CharSequenceWrapper { public object __ref; public static CharSequenceWrapper Cast(object o) { CharSequenceWrapper s; if(o is string) { s.__ref = o; return s; } s.__ref = (CharSequence)o; return s; } public static bool IsInstance(object o) { return o is string || o is CharSequence; } public object ToObject() { return __ref; } public static implicit operator CharSequenceWrapper (string s) { CharSequenceWrapper seq; seq.__ref = s; return seq; } public char charAt(int i) { if(__ref is string) { return StringHelper.charAt((string)__ref, i); } return ((CharSequence)__ref).charAt(i); } // ... other methods ... } Jonathan -----Original Message----- From: ikv...@li... [mailto:ikv...@li...] On Behalf Of Jeroen Frijters Sent: Wednesday, October 22, 2003 8:06 AM To: Jonathan Pierce Cc: ikv...@li... Subject: RE: [Ikvm-developers] Ghosts and generics Jonathan, You wrote: > >>If I statically know that the type is a string, > >>why do I need all this complicated stuff? I can just call > >>StringHelper.charAt(). > > The example wasn't complete enough to illustrate the point. > You can't just call StringHelper since you don't know to > use it from the string type in a generic way. > > The idea is to use overloaded methods so you can just plug in > the type in the generic call. You don't need to know to use the > StringHelper class for strings, you can just call the generic > charAt method with the string type like I do in this updated > version of the example: Why use generics? I must still be missing something, but wouldn't it be much easier to use overloading: public class CharSequenceHelper { public static char charAt(string s int i) { ... } public static char charAt(CharSequence s, int i) { ... } } BTW, what do you think of my new value type approach? Regards, Jeroen ------------------------------------------------------- This SF.net email is sponsored by OSDN developer relations Here's your chance to show off your extensive product knowledge We want to know what you know. Tell us and you have a chance to win $100 http://www.zoomerang.com/survey.zgi?HRPT1X3RYQNC5V4MLNSV3E54 _______________________________________________ Ikvm-developers mailing list Ikv...@li... https://lists.sourceforge.net/lists/listinfo/ikvm-developers |