Implicit overloads, non static

  • Thread starter Chad Z. Hower aka Kudzu
  • Start date
C

Chad Z. Hower aka Kudzu

I have defined some implicit convertors so that I can do:

MyStruct x = 4;

The implicit convert the 4 into MyStruct. But its essentially a copy
constructor and thus if I had:

MyStruct x;
x.SomethingElse = 5;
x = 4;

Now x.SomethingElse will be 0, because x is a new instance. Ok - all proper
and as exected - no questions here.

What I would *like* to do is this. Have the 5 update the object = not replace
it. I shudder to compare this to VB's old "default properties" but
essentially soemething like that.

This is really a non static overload, and as I understand it, C# does not
support this correct? And also there is no way to access the current instance
in the implicit convertors?


--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Empower ASP.NET with IntraWeb
http://www.atozed.com/IntraWeb/
 
J

Jon Skeet [C# MVP]

Chad Z. Hower aka Kudzu said:
I have defined some implicit convertors so that I can do:

MyStruct x = 4;

The implicit convert the 4 into MyStruct. But its essentially a copy
constructor and thus if I had:

MyStruct x;
x.SomethingElse = 5;
x = 4;

Now x.SomethingElse will be 0, because x is a new instance. Ok - all proper
and as exected - no questions here.

What I would *like* to do is this. Have the 5 update the object = not replace
it. I shudder to compare this to VB's old "default properties" but
essentially soemething like that.

This is really a non static overload, and as I understand it, C# does not
support this correct? And also there is no way to access the current instance
in the implicit convertors?

I don't believe there's any way to do this, and frankly I'm glad -
things like the above would make your code *very* unintuitive, IMO.
Heck, even implicit conversions are bad enough in that respect, without
further abuse...
 
C

Chad Z. Hower aka Kudzu

Jon Skeet said:
I don't believe there's any way to do this, and frankly I'm glad -

I have mixed feeling on it. In VB (ack!) it certainly caused a lot of
issues, but that was because VB never handled objects properly.

But the fact that VS already includes support for implicits, etc I think it
might be a good extension but havent fully thought out all the consequences
yet. At this point I just wanted to confirm that it does not exist, so I
can proceed with what I have.
things like the above would make your code *very* unintuitive, IMO.
Heck, even implicit conversions are bad enough in that respect, without
further abuse...

Anything can make your code uninintuitive, especially when abused. In fact
if I want unintuitive code I can go to C++ (or just putz around with C#'s C
style for loop, a never ending source of careless bugs). :) But implicit
operators do not themselves make code unintuitive - the user does. Implicit
operators are a *very* important feature of C# IMO and have proven
incredibly useful in practice.

Operator overloads can make a mess in the wrong hands too. But Id much
rather have the scalpel that C# is, than a chain saw. C# is very nice in
that *most* of it is implemented in "itself" rather than compiler magic,
although a lot of that remains too.


--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Make your ASP.NET applications run faster
http://www.atozed.com/IntraWeb/
 
J

Jon Skeet [C# MVP]

Chad Z. Hower aka Kudzu said:
I have mixed feeling on it. In VB (ack!) it certainly caused a lot of
issues, but that was because VB never handled objects properly.

But the fact that VS already includes support for implicits, etc I think it
might be a good extension but havent fully thought out all the consequences
yet. At this point I just wanted to confirm that it does not exist, so I
can proceed with what I have.

Unless I've missed something big, it doesn't, for which I'm heartily
glad.

Any reason not to just use a property or method?
Anything can make your code uninintuitive, especially when abused. In fact
if I want unintuitive code I can go to C++ (or just putz around with C#'s C
style for loop, a never ending source of careless bugs). :)

What kind of bug are you thinking of? I can't remember the last bug I
had due to a for loop itself...
But implicit
operators do not themselves make code unintuitive - the user does. Implicit
operators are a *very* important feature of C# IMO and have proven
incredibly useful in practice.

I can't remember *ever* writing one, in fact... the predefined ones are
useful, particularly those involving TimeSpan and DateTime, but they're
very rarely useful on a user basis, IMO.
Operator overloads can make a mess in the wrong hands too. But Id much
rather have the scalpel that C# is, than a chain saw. C# is very nice in
that *most* of it is implemented in "itself" rather than compiler magic,
although a lot of that remains too.

I would say that any assignment to a variable which only changes *part*
of the data associated with that variable counts as a bad move, myself.
 
S

Steve Walker

Jon Skeet said:
I can't remember *ever* writing one, in fact... the predefined ones are
useful, particularly those involving TimeSpan and DateTime, but they're
very rarely useful on a user basis, IMO.

The only one real use I've found is in a class a bit like this:

public abstract class ParameterBase
{
protected SqlParameter underlyingParameter;
......
public static implicit operator SqlParameter (ParameterBase p)
{
return p.underlyingParameter;
}
}

The point of this is simply to fake polymorphic behaviour. This
originally came about from a desire to provide a library of custom
parameters mapping directly to a set of SQLServer user defined data
types. What I really wanted to do was subclass SqlParameter, but it's
sealed. This solution allows:

cmd.Parameters.Add(new IPAddressParameter("@RemoteAddr", remoteAddr));

and, for some subclasses which fix the parameter name:

cmd.Parameters.Add(new PortalIDParameter(portalID));

The following would be more explicit but, in this situation, less tidy:

cmd.Parameters.Add((SqlParameter)new PortalIDParameter(portalID));
cmd.Parameters.Add((new PortalIDParameter(portalID)).SqlParameter);

It isn't a design I would have used had SqlParameter or SqlCommand been
under my control, though, and it isn't the kind of thing I would do for
a domain model class.
 
C

Chad Z. Hower aka Kudzu

Jon Skeet said:
Any reason not to just use a property or method?

For the non copy constructor behaviour, it might be considered a bit of
syntactic sugar.

For the *existing* copy constructor behavior in C#, there is of course no
way to replace that with just a property.

But the idea is that C# allows users to create new simple value (or complex
classes) types, and easily allow them to interact with int and other. There
are some examples in the help. The examples are good code, but they arent
really good examples for showing their usefulness.

But imagine that I need a BCD class. I can make it a value type (struct)
(or a classs).

BCD xValue;

xValue = 400;

int i = 4;

xSum = xValue + i;

This all works and is much cleaner, because of the implicit conversions
that you didnt find a use for. :) This is in fact a very simplistic
example, there are much more advanced and better uses, one of which I'll be
writing a paper on soon as Im presenting on it at SDA Asia in Singapore
this month.

I know Jon that your much more advanced than the majority of this group,
but dont assume just because you've not seen or needed the usefulnes of
something that it is inherently bad or unuseful. I dont use parts of the
FCL, but that doesnt make them useless.
What kind of bug are you thinking of? I can't remember the last bug I
had due to a for loop itself...

The conditions are often goofed up by developers depending on the base of
the indexer 0 or 1, and its terminator (i<50, or i<=50). Sure we all know
the proper format of the c style for, but its a very common source of bugs,
and Im even ocassionaly caught by it. While I dont mind that they have it
in C#, I much prefer my developers use while/repeats in the more advanced
permutations of the for. For the 99% of the simple cases, it would be much
better if C# had also added a simple:
for int i = 1 to 50 step 2 etc.. Maybe a C style mutation would be more
like:
for (int 1, 1, 50, 2) or something, but none the less would reduce bugs as
its harder to make "stupid" mistakes this this form, and the 1-2% cases
that fall outside this construct users could use the existing for, or a
repeat style loop.
I can't remember *ever* writing one, in fact... the predefined ones are

See above.
useful, particularly those involving TimeSpan and DateTime, but they're
very rarely useful on a user basis, IMO.

Thats not true. :) If you are a user who mostly uses classes, which in fact
is the majority of users I agree. However if they are useful to the
builders of the FCL, they are very useful to builders of other class
libraries too.
I would say that any assignment to a variable which only changes *part*
of the data associated with that variable counts as a bad move, myself.

Quite possibly. It fully depends how its implemented. Imagine the BCD
example above - imagine that it might be useful to on its constructor
specify a size.

BCD xValue = new BCD(10);

xValue = 400;

int i = 4;

xSum = xValue + i;

But when I do xValue = 400, the 10 argument will be lost because of copy
constructor behavior. Sure, the answer is make it a property but then the
BCD loses its ability to work as a "simple" type. Im not saying whether or
not such a feature is good or bad - as I said it made a mess in VB, but
that was because of its poor handling of objects. But the current copy
constructor behaviour is VERY good and in no way would I ever want to see
that removed.



--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Develop ASP.NET applications easier and in less time:
http://www.atozed.com/IntraWeb/
 
J

Jon Skeet [C# MVP]

Chad Z. Hower aka Kudzu said:
For the non copy constructor behaviour, it might be considered a bit of
syntactic sugar.

For the *existing* copy constructor behavior in C#, there is of course no
way to replace that with just a property.

But the idea is that C# allows users to create new simple value (or complex
classes) types, and easily allow them to interact with int and other. There
are some examples in the help. The examples are good code, but they arent
really good examples for showing their usefulness.

<snip>

Sure, and I can see the use occasionally - but I don't think *most*
devs need to overload operators.

I know Jon that your much more advanced than the majority of this group,
but dont assume just because you've not seen or needed the usefulnes of
something that it is inherently bad or unuseful. I dont use parts of the
FCL, but that doesnt make them useless.

I didn't say they were useless, but I would certainly take issue with
your claim that they're a "*very* important" feature of C#.

Going back to your original question, however, the ability to set only
part of a value on assignment is something which I believe would
*always* be better done with a property or method.
The conditions are often goofed up by developers depending on the base of
the indexer 0 or 1, and its terminator (i<50, or i<=50).

Just how often is often? As I say, I can't remember the last time I
wrote such a bug - and come to think of it, I can't remember the last
time I saw one in a colleague's code either.

Personally I find while loops take much longer to check for that kind
of error.
Thats not true. :) If you are a user who mostly uses classes, which in fact
is the majority of users I agree. However if they are useful to the
builders of the FCL, they are very useful to builders of other class
libraries too.

Sure - so they're very rarely useful. They may be very useful to a very
few people, but I think that comes under "very rarely useful on a user
basis".
Quite possibly. It fully depends how its implemented.

No, it's a bad idea on principle, IMO.
Imagine the BCD
example above - imagine that it might be useful to on its constructor
specify a size.

BCD xValue = new BCD(10);

xValue = 400;

int i = 4;

xSum = xValue + i;

But when I do xValue = 400, the 10 argument will be lost because of copy
constructor behavior.

And that's exactly what I'd *always* expect. If I tell a variable to
have a new value, it had better *have* a new value afterwards. That's
what I expect. It's a simple rule - why try to break it and confuse
people?
Sure, the answer is make it a property but then the
BCD loses its ability to work as a "simple" type. Im not saying whether or
not such a feature is good or bad - as I said it made a mess in VB, but
that was because of its poor handling of objects. But the current copy
constructor behaviour is VERY good and in no way would I ever want to see
that removed.

Not sure what copy constructor behaviour you mean - could you
elaborate?
 
D

Daniel O'Connell [C# MVP]

The conditions are often goofed up by developers depending on the base of
the indexer 0 or 1, and its terminator (i<50, or i<=50). Sure we all know
the proper format of the c style for, but its a very common source of
bugs,
and Im even ocassionaly caught by it. While I dont mind that they have it
in C#, I much prefer my developers use while/repeats in the more advanced
permutations of the for. For the 99% of the simple cases, it would be much
better if C# had also added a simple:
for int i = 1 to 50 step 2 etc.. Maybe a C style mutation would be more
like:
for (int 1, 1, 50, 2) or something, but none the less would reduce bugs as

foreach ( int x in 1..50 : 2)

;)
 
C

Chad Z. Hower aka Kudzu

Daniel O'Connell said:
foreach ( int x in 1..50 : 2)

You made my heart jump for a minute - thought there was something in C# I
didnt know about!

But I certainly would not argue with such a syntax - in fact when I get
sometime I'll show you whave I've actaully done. :)


--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Make your ASP.NET applications run faster
http://www.atozed.com/IntraWeb/
 
C

Chad Z. Hower aka Kudzu

Daniel O'Connell said:
foreach ( int x in 1..50 : 2)

I actually had this idea before you posted - but figured Id save it for a
rainy day. But it was very easy, took me all of 5 minutes so I decided to
do it.

foreach (int i in new Counter(1, 5)) {
Console.WriteLine(i.ToString());
}

Yes it works. :) This is the really neat part of C# and .NET, its very
extensible. Of course this is slower - but unless you have a very tight
running loop, the difference will never ever be noticed. The counter class
is below for the curious. I havent adapted it to count down or anything.


Counter class:

public class Counter {

// This enumerator is not thread safe or multi enumerator safe.
// But its usage pattern does not require such.
public class CounterEnumerator {
private Counter _Counter;

internal CounterEnumerator(Counter aCounter) {
_Counter = aCounter;
}

public bool MoveNext() {
_Counter._Current += _Counter._Step;
return _Counter._Current <= _Counter._End;
}

public int Current {
get { return _Counter._Current; }
}
}

private int _Begin;
private int _End;
private int _Step;
private int _Current;

public Counter(int aBegin, int aEnd) : this(aBegin, aEnd, 1) {
}

public Counter(int aBegin, int aEnd, int aStep) {
_Current = aBegin - 1;
_Begin = aBegin;
_End = aEnd;
_Step = aStep;
}

public CounterEnumerator GetEnumerator() {
return new CounterEnumerator(this);
}


--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Develop ASP.NET applications easier and in less time:
http://www.atozed.com/IntraWeb/
 
C

Chad Z. Hower aka Kudzu

Jon Skeet said:
Sure, and I can see the use occasionally - but I don't think *most*
devs need to overload operators.

No, they dont. But most developers dont build component sets - but Im sure
glad they are there for the developers of the FCL to make the FCL easier
for us to use - and for developers like myself who build FCL like libraries
that others (And myself) use.
I didn't say they were useless, but I would certainly take issue with
your claim that they're a "*very* important" feature of C#.

They are - becuase the FCL is written in C#. And since we use the FCL -
that makes it important. Without such, the FCL would not be as nice as it
is for us to use, and C# would be like the old VB. A class USING language,
but not a good class building language.
Going back to your original question, however, the ability to set only
part of a value on assignment is something which I believe would
*always* be better done with a property or method.

Quite possibly - I didnt dispute that. I just wanted to verify that my
findings were correct in that it didnt exist.
Just how often is often? As I say, I can't remember the last time I
wrote such a bug - and come to think of it, I can't remember the last
time I saw one in a colleague's code either.

I work with a lot of teams - and I see it fairly enough to know its a
roach. Ive also seen the most experienced C++ developers make this mistake
too.
Personally I find while loops take much longer to check for that kind
of error.

Not simple indexers.

for (int i = 1; i <= 5; i++)
Console.WriteLine(i);
}

for (int i = 1 to 5)
Console.WriteLine(i);
}

Only a diehard C++ developer (Which most are) would say the first one is
simpler to understand. I dont dispute its more expandable, but 99% of the
time thats never needed.
Sure - so they're very rarely useful. They may be very useful to a very
few people, but I think that comes under "very rarely useful on a user
basis".

DIRECTLY maybe. But you USE the FCL. So indirectly they are VERY useful.
No, it's a bad idea on principle, IMO.

If its a bad idea - then so are the implicit convertors.
And that's exactly what I'd *always* expect. If I tell a variable to
have a new value, it had better *have* a new value afterwards. That's
what I expect. It's a simple rule - why try to break it and confuse
people?

It DOES have a new value- but its a value type - in fact its not even a
"value", it just mimics a value. But again - see above, Im not disputing
that default properties would be a good thing. My point of disagreement
with your statements regards existing behaviour in C# that you find little
use for and thus label as unimportant.
Not sure what copy constructor behaviour you mean - could you
elaborate?

Copy constructor is what implicit conversions cause.

BCD = 4;

This actually causes a new BCD instance to be created, and 4 is passed to
it.


--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Empower ASP.NET with IntraWeb
http://www.atozed.com/IntraWeb/
 
J

Jon Skeet [C# MVP]

Chad Z. Hower aka Kudzu said:
I actually had this idea before you posted - but figured Id save it for a
rainy day. But it was very easy, took me all of 5 minutes so I decided to
do it.

foreach (int i in new Counter(1, 5)) {
Console.WriteLine(i.ToString());
}

Yes it works. :) This is the really neat part of C# and .NET, its very
extensible. Of course this is slower - but unless you have a very tight
running loop, the difference will never ever be noticed. The counter class
is below for the curious. I havent adapted it to count down or anything.

It's even easier with "yield" in 2.0:

public class Counter : IEnumerable
{
int from;
int to;

public Counter (int from, int to)
{
this.from = from;
this.to = to;
}

public IEnumerator GetEnumerator()
{
for (int i = from; i <= to; i++)
{
yield return i;
}
}
}

(I missed out the step part for clarity - it's obvious how you'd put it
in.)
 
J

Jon Skeet [C# MVP]

Chad Z. Hower aka Kudzu said:
No, they dont. But most developers dont build component sets - but Im sure
glad they are there for the developers of the FCL to make the FCL easier
for us to use - and for developers like myself who build FCL like libraries
that others (And myself) use.

I'm glad they're available - but I'm also glad they're not flexible
enough to allow really nasty abuse.
They are - becuase the FCL is written in C#.

Much of it is, yes. There's no need for it to all be, however.
And since we use the FCL -
that makes it important. Without such, the FCL would not be as nice as it
is for us to use, and C# would be like the old VB. A class USING language,
but not a good class building language.

Put it this way - Java doesn't have operator overloading, but given the
choice between introducing that or introducing something similar to the
C# "using" statement, I'd go for the latter any day. Events, properties
and delegates would be higher up my list than operator overloading,
too. I'm happy enough calling methods rather than using operators when
I need to - it's never been a real headache for me in Java.

Reasonably important, maybe, but *very* important (your emphasis, not
mine)? Not really - not for me as either a class library user or
creator.
Quite possibly - I didnt dispute that. I just wanted to verify that my
findings were correct in that it didnt exist.

Well, you've disputed whether it's a matter of implementation rather
than principle. The fact that you'd *like* to do something which to me
seems completely abhorrent suggests that we've got a significant
disagreement.
I work with a lot of teams - and I see it fairly enough to know its a
roach. Ive also seen the most experienced C++ developers make this mistake
too.

I guess we can only talk about our own experiences, however different
they may be. The discrepancy does seem very odd though - I wonder what
the cause is.
Not simple indexers.

for (int i = 1; i <= 5; i++)
Console.WriteLine(i);
}

for (int i = 1 to 5)
Console.WriteLine(i);
}

Only a diehard C++ developer (Which most are) would say the first one is
simpler to understand. I dont dispute its more expandable, but 99% of the
time thats never needed.

Sure, that's clearer - but I wasn't disputing that. You said you prefer
your developers to use while loops, and I was saying that I find them
harder to read than for loops. Maybe we're talking at cross-purposes
though.
DIRECTLY maybe. But you USE the FCL. So indirectly they are VERY useful.

Only if you'd really find life hard without them. I don't find life
hard in Java where I don't have them, therefore they're not that
important to me.
If its a bad idea - then so are the implicit convertors.

And for almost every use, I'd go along with that. Other than the types
defined in the language spec, I think it's pretty much always a bad
idea to have implicit conversion. Being able to provide *explicit*
conversion operators is not quite so bad, although it should still be
used with a lot of care.
It DOES have a new value- but its a value type - in fact its not even a
"value", it just mimics a value.

But that new value isn't entirely derived from the expression on the
right hand side of the "=" - and that's *very* counter-intuitive. Not
due to implementation, but due to the very principle of the idea.
But again - see above, Im not disputing
that default properties would be a good thing. My point of disagreement
with your statements regards existing behaviour in C# that you find little
use for and thus label as unimportant.

No, I think we're disagreeing more fundamentally. Your examples have
shown that you think it's not always a bad idea to violate the
principle that if I do:

<variable> = <expression>;

I should be able to look at <expression> and completely know the value
of the variable. That's not a matter of what's important or not, it's a
case of what violates entirely reasonable assumptions that pretty much
every developer makes subconciously all the time.
Copy constructor is what implicit conversions cause.

BCD = 4;

This actually causes a new BCD instance to be created, and 4 is passed to
it.

Right. I'm not sure I'd call that a copy constructor myself, but that's
not terribly important. (I usually wouldn't use the phrase "copy
constructor" outside C++, and then only when the parameter to the
constructor was of the same type as the object being constructed.)
 
D

Daniel O'Connell [C# MVP]

Chad Z. Hower aka Kudzu said:
You made my heart jump for a minute - thought there was something in C# I
didnt know about!

Sorry, I just realized I did that. No, its just something thats been
discussed ad nausem in these groups.
 
C

Chad Z. Hower aka Kudzu

Jon Skeet said:
Well, you've disputed whether it's a matter of implementation rather
than principle. The fact that you'd *like* to do something which to me

I didnt necessarily want to do it - the code I posted was just to show
"What" it would do. Im using the copy constructor behaviour and am just
fine with that.
I guess we can only talk about our own experiences, however different
they may be. The discrepancy does seem very odd though - I wonder what
the cause is.

It's easy - 1 to 5, 0, to 4, goofing up of the condition mostly.
Sure, that's clearer - but I wasn't disputing that. You said you prefer
your developers to use while loops, and I was saying that I find them
harder to read than for loops. Maybe we're talking at cross-purposes
though.

Aah - sorry I should have clarified that. I prefer they use while loops
*when* its not a simple for i = 1 to 5 condition. Certainly not for that
condition. :)
Only if you'd really find life hard without them. I don't find life
hard in Java where I don't have them, therefore they're not that
important to me.

I find a lot of things hard in Java. Ack what they call properties... They
are methods! There's no property about it - its a blooddy pattern I could
do in VB... reminds me of OOP in SAS.
And for almost every use, I'd go along with that. Other than the types
defined in the language spec, I think it's pretty much always a bad
idea to have implicit conversion. Being able to provide *explicit*
conversion operators is not quite so bad, although it should still be
used with a lot of care.

Here is where we will strongly disagree then for sure.
No, I think we're disagreeing more fundamentally. Your examples have
shown that you think it's not always a bad idea to violate the
principle that if I do:

<variable> = <expression>;

I should be able to look at <expression> and completely know the value
of the variable. That's not a matter of what's important or not, it's a
case of what violates entirely reasonable assumptions that pretty much
every developer makes subconciously all the time.

But you *do* know the value. Becuase its a new value type.

BCD x = 4;

decimal i = x;

i equals 4.

It *is* a new value type - and thus its value is 4. There are many other
non value type uses for implicits too.
Right. I'm not sure I'd call that a copy constructor myself, but that's
not terribly important. (I usually wouldn't use the phrase "copy
constructor" outside C++, and then only when the parameter to the
constructor was of the same type as the object being constructed.)

Yes - true. Its not a copy constructor, its similar behavioru. I introduced
the term when I was describing some behaviour, and its gone out of context
since then.


--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Develop ASP.NET applications easier and in less time:
http://www.atozed.com/IntraWeb/
 
C

Chad Z. Hower aka Kudzu

Daniel O'Connell said:
Sorry, I just realized I did that. No, its just something thats been
discussed ad nausem in these groups.

Actually if it "Was" that way it would be very bad unless it was a special
syntax. When I saw 1..50, I read "set of 1 to 50" (Delphi). So if it creates
set - that would be BIG, and also the in would not guarantee order....

But non the less Id be ok with that syntax if it was interpeted as a for loop
and not a set. :)


--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Empower ASP.NET with IntraWeb
http://www.atozed.com/IntraWeb/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top