Home All Groups Group Topic Archive Search About

Implicit conversion design issues

Author
25 Mar 2005 1:32 AM
Girish
Im trying to understand implicit type conversions from object -> string and
vice versa.

I have two classes, one Driver and one called StringWrapper. These are just
test classes that try and emulate the pattern im trying to follow in an
existing project.

These are my steps:
1) I have a method "printMe" existing in the application which originally
used to take in a string. This method is static and sits in the Driver
class. I cannot remove this method since it public and is used all over the
application.
2) Now, Ive realised that I need to do some parsing and cleaning up of the
string before the method can continue to execute its logic (printMe).
3) My solution was to change the method sig to take in a StringWrapper
class, created by me, that will take in an implicit string and return a
StringWrapper object with the cleaned up string.
4) Now, when the StringWapper object is used by the code in the method
printMe, I want to treat it as a String object and not a StringWrapper
object. So what Ive done is create another implicit conversion from
StringWrapper to String.

I hope this makes sense at this point. Essentially Im tring to minimize code
changes in the code that calls my printMe method so that it knows of only
String objects. AND the reminaing logic in printMe function should only know
of String objects as well. So the StringWrapper class will essentially
convert string to an object of its type, do the cleaning of the string and
then, whereever the StringWrapper instance is used in printMe method, it
should expose itself as a String instead.

So my question is
1) In my printMe method, I had a statement called
Console.Write(val.ToLower()). This threw me an exception because it said the
StringWrapper does not support the ToLower method. How come even though I
have an implicit conversion?
2) If I do Console.Write(((string)val).ToLower()); it works!! Even though
this is an explicit conversion and I havent defined any explicit
conversions....

Im kinda lost here.... can anyone help me with a solution to this problem?

Thanks,
Girish

Driver Class
-------------
using System;
namespace test1 {
class Driver {
  //old func sig was; static public void printMe(String val)
  static public void printMe(StringWrapper val) {
   //Console.Write(val.ToLower()); //old
   Console.Write(((string)val).ToLower());
  }

  [STAThread]
  static void Main(string[] args) {
   String b = "Testing 123";
   Driver.printMe(b);

   //wait for input before exiting
   Console.Read();
  }
}
}


StringWrapper Class
---------------------
using System;
namespace test1 {
public class StringWrapper {
  private String _val;

  public String val {
   get { return _val; }
  }

  public StringWrapper(String val) {
   this._val = val;
  }

  static public implicit operator StringWrapper(String val) {
   val += " (im changed)";
   return new StringWrapper(val);
  }

  static public implicit operator string(StringWrapper val) {
   return val.val;
  }
}
}

Author
25 Mar 2005 1:41 AM
Girish
For those of you who thought I didnt attach any code, since ive wrote a long
email, you can find the code at the bottom of my earlier post. I know some
people must be going... OK im reading all this stuff.. so wheres the code
now???

Show quote
:-):-):-):-)


"Girish" <gba***@tietronixinc.com> wrote in message
news:e%23NY7pNMFHA.3544@TK2MSFTNGP10.phx.gbl...
> Im trying to understand implicit type conversions from object -> string
> and vice versa.
>
> I have two classes, one Driver and one called StringWrapper. These are
> just test classes that try and emulate the pattern im trying to follow in
> an existing project.
>
> These are my steps:
> 1) I have a method "printMe" existing in the application which originally
> used to take in a string. This method is static and sits in the Driver
> class. I cannot remove this method since it public and is used all over
> the application.
> 2) Now, Ive realised that I need to do some parsing and cleaning up of the
> string before the method can continue to execute its logic (printMe).
> 3) My solution was to change the method sig to take in a StringWrapper
> class, created by me, that will take in an implicit string and return a
> StringWrapper object with the cleaned up string.
> 4) Now, when the StringWapper object is used by the code in the method
> printMe, I want to treat it as a String object and not a StringWrapper
> object. So what Ive done is create another implicit conversion from
> StringWrapper to String.
>
> I hope this makes sense at this point. Essentially Im tring to minimize
> code changes in the code that calls my printMe method so that it knows of
> only String objects. AND the reminaing logic in printMe function should
> only know of String objects as well. So the StringWrapper class will
> essentially convert string to an object of its type, do the cleaning of
> the string and then, whereever the StringWrapper instance is used in
> printMe method, it should expose itself as a String instead.
>
> So my question is
> 1) In my printMe method, I had a statement called
> Console.Write(val.ToLower()). This threw me an exception because it said
> the StringWrapper does not support the ToLower method. How come even
> though I have an implicit conversion?
> 2) If I do Console.Write(((string)val).ToLower()); it works!! Even though
> this is an explicit conversion and I havent defined any explicit
> conversions....
>
> Im kinda lost here.... can anyone help me with a solution to this problem?
>
> Thanks,
> Girish
>
> Driver Class
> -------------
> using System;
> namespace test1 {
> class Driver {
>  //old func sig was; static public void printMe(String val)
>  static public void printMe(StringWrapper val) {
>   //Console.Write(val.ToLower()); //old
>   Console.Write(((string)val).ToLower());
>  }
>
>  [STAThread]
>  static void Main(string[] args) {
>   String b = "Testing 123";
>   Driver.printMe(b);
>
>   //wait for input before exiting
>   Console.Read();
>  }
> }
> }
>
>
> StringWrapper Class
> ---------------------
> using System;
> namespace test1 {
> public class StringWrapper {
>  private String _val;
>
>  public String val {
>   get { return _val; }
>  }
>
>  public StringWrapper(String val) {
>   this._val = val;
>  }
>
>  static public implicit operator StringWrapper(String val) {
>   val += " (im changed)";
>   return new StringWrapper(val);
>  }
>
>  static public implicit operator string(StringWrapper val) {
>   return val.val;
>  }
> }
> }
>
>
Author
25 Mar 2005 3:43 AM
VJ
Oh ... Ok maybe this seems simple to me.. but I might miss something
application specfic.. if you are able to change the signature.. I assume you
have the source code.. why can't you write the cleanup code as the first few
lines of the printMe and make it simple?

VJ

Show quote
"Girish" <gba***@tietronixinc.com> wrote in message
news:%23E%23zSvNMFHA.2604@TK2MSFTNGP10.phx.gbl...
> For those of you who thought I didnt attach any code, since ive wrote a
> long email, you can find the code at the bottom of my earlier post. I know
> some people must be going... OK im reading all this stuff.. so wheres the
> code now???
>
> :-):-):-):-)
>
>
> "Girish" <gba***@tietronixinc.com> wrote in message
> news:e%23NY7pNMFHA.3544@TK2MSFTNGP10.phx.gbl...
>> Im trying to understand implicit type conversions from object -> string
>> and vice versa.
>>
>> I have two classes, one Driver and one called StringWrapper. These are
>> just test classes that try and emulate the pattern im trying to follow in
>> an existing project.
>>
>> These are my steps:
>> 1) I have a method "printMe" existing in the application which originally
>> used to take in a string. This method is static and sits in the Driver
>> class. I cannot remove this method since it public and is used all over
>> the application.
>> 2) Now, Ive realised that I need to do some parsing and cleaning up of
>> the string before the method can continue to execute its logic (printMe).
>> 3) My solution was to change the method sig to take in a StringWrapper
>> class, created by me, that will take in an implicit string and return a
>> StringWrapper object with the cleaned up string.
>> 4) Now, when the StringWapper object is used by the code in the method
>> printMe, I want to treat it as a String object and not a StringWrapper
>> object. So what Ive done is create another implicit conversion from
>> StringWrapper to String.
>>
>> I hope this makes sense at this point. Essentially Im tring to minimize
>> code changes in the code that calls my printMe method so that it knows of
>> only String objects. AND the reminaing logic in printMe function should
>> only know of String objects as well. So the StringWrapper class will
>> essentially convert string to an object of its type, do the cleaning of
>> the string and then, whereever the StringWrapper instance is used in
>> printMe method, it should expose itself as a String instead.
>>
>> So my question is
>> 1) In my printMe method, I had a statement called
>> Console.Write(val.ToLower()). This threw me an exception because it said
>> the StringWrapper does not support the ToLower method. How come even
>> though I have an implicit conversion?
>> 2) If I do Console.Write(((string)val).ToLower()); it works!! Even though
>> this is an explicit conversion and I havent defined any explicit
>> conversions....
>>
>> Im kinda lost here.... can anyone help me with a solution to this
>> problem?
>>
>> Thanks,
>> Girish
>>
>> Driver Class
>> -------------
>> using System;
>> namespace test1 {
>> class Driver {
>>  //old func sig was; static public void printMe(String val)
>>  static public void printMe(StringWrapper val) {
>>   //Console.Write(val.ToLower()); //old
>>   Console.Write(((string)val).ToLower());
>>  }
>>
>>  [STAThread]
>>  static void Main(string[] args) {
>>   String b = "Testing 123";
>>   Driver.printMe(b);
>>
>>   //wait for input before exiting
>>   Console.Read();
>>  }
>> }
>> }
>>
>>
>> StringWrapper Class
>> ---------------------
>> using System;
>> namespace test1 {
>> public class StringWrapper {
>>  private String _val;
>>
>>  public String val {
>>   get { return _val; }
>>  }
>>
>>  public StringWrapper(String val) {
>>   this._val = val;
>>  }
>>
>>  static public implicit operator StringWrapper(String val) {
>>   val += " (im changed)";
>>   return new StringWrapper(val);
>>  }
>>
>>  static public implicit operator string(StringWrapper val) {
>>   return val.val;
>>  }
>> }
>> }
>>
>>
>
>
Author
25 Mar 2005 4:40 AM
Girish
True, I could have. But for the future, I can just let everyone know, use
the StringWrapper class from now on people for your string manuplilation.
This is easier than telling everyone, hey when you write a method in the
future, remember to call this other helper function and make sure its called
before any other code.

I dont know, but i usually like to have more than one way of doing things
and pick whats appropriate.... and if the implicit cast mehod is not the way
to go... id really appreciate it if someone can help me understand why. :)

thanks!
Girish

Show quote
"VJ" <vijayba***@yahoo.com> wrote in message
news:uBJIizOMFHA.3380@TK2MSFTNGP15.phx.gbl...
> Oh ... Ok maybe this seems simple to me.. but I might miss something
> application specfic.. if you are able to change the signature.. I assume
> you have the source code.. why can't you write the cleanup code as the
> first few lines of the printMe and make it simple?
>
> VJ
>
> "Girish" <gba***@tietronixinc.com> wrote in message
> news:%23E%23zSvNMFHA.2604@TK2MSFTNGP10.phx.gbl...
>> For those of you who thought I didnt attach any code, since ive wrote a
>> long email, you can find the code at the bottom of my earlier post. I
>> know some people must be going... OK im reading all this stuff.. so
>> wheres the code now???
>>
>> :-):-):-):-)
>>
>>
>> "Girish" <gba***@tietronixinc.com> wrote in message
>> news:e%23NY7pNMFHA.3544@TK2MSFTNGP10.phx.gbl...
>>> Im trying to understand implicit type conversions from object -> string
>>> and vice versa.
>>>
>>> I have two classes, one Driver and one called StringWrapper. These are
>>> just test classes that try and emulate the pattern im trying to follow
>>> in an existing project.
>>>
>>> These are my steps:
>>> 1) I have a method "printMe" existing in the application which
>>> originally used to take in a string. This method is static and sits in
>>> the Driver class. I cannot remove this method since it public and is
>>> used all over the application.
>>> 2) Now, Ive realised that I need to do some parsing and cleaning up of
>>> the string before the method can continue to execute its logic
>>> (printMe).
>>> 3) My solution was to change the method sig to take in a StringWrapper
>>> class, created by me, that will take in an implicit string and return a
>>> StringWrapper object with the cleaned up string.
>>> 4) Now, when the StringWapper object is used by the code in the method
>>> printMe, I want to treat it as a String object and not a StringWrapper
>>> object. So what Ive done is create another implicit conversion from
>>> StringWrapper to String.
>>>
>>> I hope this makes sense at this point. Essentially Im tring to minimize
>>> code changes in the code that calls my printMe method so that it knows
>>> of only String objects. AND the reminaing logic in printMe function
>>> should only know of String objects as well. So the StringWrapper class
>>> will essentially convert string to an object of its type, do the
>>> cleaning of the string and then, whereever the StringWrapper instance is
>>> used in printMe method, it should expose itself as a String instead.
>>>
>>> So my question is
>>> 1) In my printMe method, I had a statement called
>>> Console.Write(val.ToLower()). This threw me an exception because it said
>>> the StringWrapper does not support the ToLower method. How come even
>>> though I have an implicit conversion?
>>> 2) If I do Console.Write(((string)val).ToLower()); it works!! Even
>>> though this is an explicit conversion and I havent defined any explicit
>>> conversions....
>>>
>>> Im kinda lost here.... can anyone help me with a solution to this
>>> problem?
>>>
>>> Thanks,
>>> Girish
>>>
>>> Driver Class
>>> -------------
>>> using System;
>>> namespace test1 {
>>> class Driver {
>>>  //old func sig was; static public void printMe(String val)
>>>  static public void printMe(StringWrapper val) {
>>>   //Console.Write(val.ToLower()); //old
>>>   Console.Write(((string)val).ToLower());
>>>  }
>>>
>>>  [STAThread]
>>>  static void Main(string[] args) {
>>>   String b = "Testing 123";
>>>   Driver.printMe(b);
>>>
>>>   //wait for input before exiting
>>>   Console.Read();
>>>  }
>>> }
>>> }
>>>
>>>
>>> StringWrapper Class
>>> ---------------------
>>> using System;
>>> namespace test1 {
>>> public class StringWrapper {
>>>  private String _val;
>>>
>>>  public String val {
>>>   get { return _val; }
>>>  }
>>>
>>>  public StringWrapper(String val) {
>>>   this._val = val;
>>>  }
>>>
>>>  static public implicit operator StringWrapper(String val) {
>>>   val += " (im changed)";
>>>   return new StringWrapper(val);
>>>  }
>>>
>>>  static public implicit operator string(StringWrapper val) {
>>>   return val.val;
>>>  }
>>> }
>>> }
>>>
>>>
>>
>>
>
>
Author
25 Mar 2005 4:53 AM
Daniel O'Connell [C# MVP]
> So my question is
> 1) In my printMe method, I had a statement called
> Console.Write(val.ToLower()). This threw me an exception because it said
> the StringWrapper does not support the ToLower method. How come even
> though I have an implicit conversion?

Implicit conversions are only applied in some circumstances, method
resolution is not one of them(atleast while resolving the method set the
type has. Conversions for parameters are considered while dealing with
overload resolution, but the type of the variable is static.) As far as the
compiler is concerned, the only methods your type has are those it or its
bases define.

> 2) If I do Console.Write(((string)val).ToLower()); it works!! Even though
> this is an explicit conversion and I havent defined any explicit
> conversions....
>

By casting here you are telling the compiler you want to cause the
conversion. Since implicit conversions do not happen during method
resolution, you have to explicitly tell the compiler to perform the
conversion and to call string::ToLower().
Author
25 Mar 2005 5:34 AM
Girish
Thanks for your reply Daniel. I have more qs, and maybe these are silly qs
but please bear with me.

1) Why does the compiler not complain that I dont have an explicit cast
specified in my type? I know you cannot have both implicit and explicit
defined but if im stating I need to envoke an explicit cast - it somehow
"understands" i really mean execute the implicit cast method.. If the answer
to this q is "well, thats the way it is...", i guess I can live with that.
:-)

2) Do conversions of types only happen during overloading? What are the
other circumstances?

3) I noticed that this pattern causes an infinite loop. Shouldnt the
complier choke at this?

  static public implicit operator StringWrapper(String val) {
   val += " (im changed)";
   //return new StringWrapper(val);
    return val;
  }

g



Show quote
"Daniel O'Connell [C# MVP]" <onyxkirx@--NOSPAM--comcast.net> wrote in
message news:Ou2fIaPMFHA.656@TK2MSFTNGP14.phx.gbl...
>> So my question is
>> 1) In my printMe method, I had a statement called
>> Console.Write(val.ToLower()). This threw me an exception because it said
>> the StringWrapper does not support the ToLower method. How come even
>> though I have an implicit conversion?
>
> Implicit conversions are only applied in some circumstances, method
> resolution is not one of them(atleast while resolving the method set the
> type has. Conversions for parameters are considered while dealing with
> overload resolution, but the type of the variable is static.) As far as
> the compiler is concerned, the only methods your type has are those it or
> its bases define.
>
>> 2) If I do Console.Write(((string)val).ToLower()); it works!! Even though
>> this is an explicit conversion and I havent defined any explicit
>> conversions....
>>
>
> By casting here you are telling the compiler you want to cause the
> conversion. Since implicit conversions do not happen during method
> resolution, you have to explicitly tell the compiler to perform the
> conversion and to call string::ToLower().
>
>
>
Author
25 Mar 2005 5:55 AM
Daniel O'Connell [C# MVP]
"Girish" <gba***@tietronixinc.com> wrote in message
news:%23D5BHxPMFHA.2420@TK2MSFTNGP12.phx.gbl...
> Thanks for your reply Daniel. I have more qs, and maybe these are silly qs
> but please bear with me.
>

Its no problem. Conversions and overloading are the most confusing parts of
the spec, atleast from a compiler writer's point of view. I don't mind
trying to explain it.

> 1) Why does the compiler not complain that I dont have an explicit cast
> specified in my type? I know you cannot have both implicit and explicit
> defined but if im stating I need to envoke an explicit cast - it somehow
> "understands" i really mean execute the implicit cast method.. If the
> answer to this q is "well, thats the way it is...", i guess I can live
> with that. :-)

Well, "thats the way it is" is pretty close to it, but its not complete, ;).
Basically the rules are an explicit cconversion must be explicitly
declared(using a cast operator), while an implicit cast may or may not be
explicit. In my opinion this is done to allow for exactly what you are
seeing here, that is permit the coder to explicitly tell the compiler to
perform a conversion in a situation where implicit conversions are not in
effect.

> 2) Do conversions of types only happen during overloading? What are the
> other circumstances?

Implicit conversions are possible during any assignment, return or parameter
pass operation(both of which you could consider an assignment and look like
or are assignments in other languages). Overload resolution takes
conversions in account to determine the proper overload, assignment takes it
in account to determine if any conversion steps are required between the
source and the target type, casting can obviously explicitly cause a
conversion, a return statement can cause .

I don't think there are any other circumstances where this happens, but I
don't have the spec on hand to be sure(can't recall off hand if implicit
conversions to bool are considered in if statements, for example).

> 3) I noticed that this pattern causes an infinite loop. Shouldnt the
> complier choke at this?
>
>  static public implicit operator StringWrapper(String val) {
>   val += " (im changed)";
>   //return new StringWrapper(val);
>    return val;
>  }
>

The compiler should probably spit out a warning that you are going to enter
an infinite loop, but it *is* legal code. The reason for this is that the
compiler cannot really tell that the infinite recursion is going to happen,
just that its likely or possible. While its obvious to us, without being
able to understand the method as a whole, the compiler could only guess as
to if you actually meant to cause recursion or not. Thus it is something it
should probably warn about, but not emit an error.
Author
25 Mar 2005 7:21 AM
Girish
Thansk for helping me out Daniel. I bet if you had a buck for every thank
you expressed by a person you helped, Im sure youd be real rich!!!! if your
not already tho.. ;-)

Thanks a million for what its worth. :-)

girish

Show quote
"Daniel O'Connell [C# MVP]" <onyxkirx@--NOSPAM--comcast.net> wrote in
message news:OfCf28PMFHA.3076@TK2MSFTNGP14.phx.gbl...
>
> "Girish" <gba***@tietronixinc.com> wrote in message
> news:%23D5BHxPMFHA.2420@TK2MSFTNGP12.phx.gbl...
>> Thanks for your reply Daniel. I have more qs, and maybe these are silly
>> qs but please bear with me.
>>
>
> Its no problem. Conversions and overloading are the most confusing parts
> of the spec, atleast from a compiler writer's point of view. I don't mind
> trying to explain it.
>
>> 1) Why does the compiler not complain that I dont have an explicit cast
>> specified in my type? I know you cannot have both implicit and explicit
>> defined but if im stating I need to envoke an explicit cast - it somehow
>> "understands" i really mean execute the implicit cast method.. If the
>> answer to this q is "well, thats the way it is...", i guess I can live
>> with that. :-)
>
> Well, "thats the way it is" is pretty close to it, but its not complete,
> ;). Basically the rules are an explicit cconversion must be explicitly
> declared(using a cast operator), while an implicit cast may or may not be
> explicit. In my opinion this is done to allow for exactly what you are
> seeing here, that is permit the coder to explicitly tell the compiler to
> perform a conversion in a situation where implicit conversions are not in
> effect.
>
>> 2) Do conversions of types only happen during overloading? What are the
>> other circumstances?
>
> Implicit conversions are possible during any assignment, return or
> parameter pass operation(both of which you could consider an assignment
> and look like or are assignments in other languages). Overload resolution
> takes conversions in account to determine the proper overload, assignment
> takes it in account to determine if any conversion steps are required
> between the source and the target type, casting can obviously explicitly
> cause a conversion, a return statement can cause .
>
> I don't think there are any other circumstances where this happens, but I
> don't have the spec on hand to be sure(can't recall off hand if implicit
> conversions to bool are considered in if statements, for example).
>
>> 3) I noticed that this pattern causes an infinite loop. Shouldnt the
>> complier choke at this?
>>
>>  static public implicit operator StringWrapper(String val) {
>>   val += " (im changed)";
>>   //return new StringWrapper(val);
>>    return val;
>>  }
>>
>
> The compiler should probably spit out a warning that you are going to
> enter an infinite loop, but it *is* legal code. The reason for this is
> that the compiler cannot really tell that the infinite recursion is going
> to happen, just that its likely or possible. While its obvious to us,
> without being able to understand the method as a whole, the compiler could
> only guess as to if you actually meant to cause recursion or not. Thus it
> is something it should probably warn about, but not emit an error.
>
Author
25 Mar 2005 5:48 AM
Brant Estes
I guess the first step is understanding what implicit and explicit
operators are.  What they effectively do, is convert one type to
another.  The difference between implicit and explicit operators, is
whether or not you need to cast or not.

Consider your own code, and assume for now you didn't implement the
implicit operator:

StringWrapper sw = new StringWrapper("some value");
string s = sw; // this will fail if you don't have an implicit operator
string s = (string)sw; // this fail if you don't have an explicit
operator.
One thing I've noticed developers have to understand, is that
converting from one type to another, doesn't just happen magically,
code needs to exist, which in this case, is the implicit and explicit
operators.

It looks like what you're trying to do, is build additional
functionality into the string class.  You probably tried what many of
us already did, and do:

public class StringWrapper : System.String {}

You probably also realized, that this is impossible, because
System.String is a sealed class (along with most of the other primitive
types you'd like to extend from time to time), so this prevents you
from inheriting from it.

Your best bet, would be to keep your implicit operators in place, to
ease development.  But in your example:

static public void printMe(StringWrapper val) {
   //Console.Write(val.ToLower())­; //old
   Console.Write(((string)val).To­Lower());
  }

The parameter "val" is of type StringWrapper, and not string.  You can
easily convert between the two using your implicit operators, but that
doesn't mean their methods are inherited from each other.

In order to use the ToLower() method, you will need to get a variable
of type string, because it's the string class which has that method
defined, not your StringWrapper.

Since you have your implicit operator defined, this a pretty simple
process:

static public void printMe(StringWrapper val) {
   //Console.Write(val.ToLower())­; //old
  string newVal = val;
   Console.Write(newVal.To­Lower());
  }

I hope this clarifies what your understanding of implicit conversions,
and how they're used.

Brant Estes
Author
25 Mar 2005 6:06 AM
Girish
Thanks for your reply Brant. It helped. Indeed, your right. I did try and
start this out by extending the String class - but I noticed that the String
class was sealed in the docs... then I started to think of a way to do what
I need to do with *minimum* impact to the calling code and the executing
code. Then i remembered that String objects can be created without having to
do a "new". And then it struck me there has to be a way I can create an
string and assign it to my own type without a "new". Passing objects into
method parameters seemed like writing stringwrapper a = "xyz" to me and
thats where all this started from. At that time I didnt know this concept is
called operator overloading. But now I know. :-)

Girish


"Brant Estes" <bra***@magenic.com> wrote in message
news:1111729696.059576.139420@g14g2000cwa.googlegroups.com...
I guess the first step is understanding what implicit and explicit
operators are.  What they effectively do, is convert one type to
another.  The difference between implicit and explicit operators, is
whether or not you need to cast or not.

Consider your own code, and assume for now you didn't implement the
implicit operator:

StringWrapper sw = new StringWrapper("some value");
string s = sw; // this will fail if you don't have an implicit operator
string s = (string)sw; // this fail if you don't have an explicit
operator.
One thing I've noticed developers have to understand, is that
converting from one type to another, doesn't just happen magically,
code needs to exist, which in this case, is the implicit and explicit
operators.

It looks like what you're trying to do, is build additional
functionality into the string class.  You probably tried what many of
us already did, and do:

public class StringWrapper : System.String {}

You probably also realized, that this is impossible, because
System.String is a sealed class (along with most of the other primitive
types you'd like to extend from time to time), so this prevents you
from inheriting from it.

Your best bet, would be to keep your implicit operators in place, to
ease development.  But in your example:

static public void printMe(StringWrapper val) {
   //Console.Write(val.ToLower())­; //old
   Console.Write(((string)val).To­Lower());
  }

The parameter "val" is of type StringWrapper, and not string.  You can
easily convert between the two using your implicit operators, but that
doesn't mean their methods are inherited from each other.

In order to use the ToLower() method, you will need to get a variable
of type string, because it's the string class which has that method
defined, not your StringWrapper.

Since you have your implicit operator defined, this a pretty simple
process:

static public void printMe(StringWrapper val) {
   //Console.Write(val.ToLower())­; //old
  string newVal = val;
   Console.Write(newVal.To­Lower());
  }

I hope this clarifies what your understanding of implicit conversions,
and how they're used.

Brant Estes

AddThis Social Bookmark Button