assignment to overloaded operator <<

I

Ian Lazarus

Hello,


My question is whether it is possible to avoid assignment on the left hand
side of an overloaded operator << expression, as in the code below. Without
the assignment, the compiler complains.



class myclass
{
public static myclass operator << (myclass lhs, int rhs)
{
return(lhs);
}

public static void Main()
{
myclass x = new myclass();
int a = 1;
int b = 2;
int c = 3;
x << a << b << c;
// error CS0201: Only assignment, call, increment, decrement, and
new // object expressions can be used as a statement
}
}



So instead, I have to write:


x = x << a << b << c;


Is there a way to avoid the assignment?



Thanks
 
D

Daniel O'Connell [C# MVP]

Ian Lazarus said:
Hello,


My question is whether it is possible to avoid assignment on the left hand
side of an overloaded operator << expression, as in the code below.
Without the assignment, the compiler complains.



class myclass
{
public static myclass operator << (myclass lhs, int rhs)
{
return(lhs);
}

public static void Main()
{
myclass x = new myclass();
int a = 1;
int b = 2;
int c = 3;
x << a << b << c;
// error CS0201: Only assignment, call, increment, decrement, and
new // object expressions can be used as a statement
}
}



So instead, I have to write:


x = x << a << b << c;


Is there a way to avoid the assignment?

No. Shifting operators, like most, are expected to perform some kind of work
and return a result. Most of the time a correctly defined operator should
not change the contents of the current object, instead returning a new one.
Therefore they require assignment. The only operator exceptions are
increment\decrement, which are implicitly assigned, and new, which runs
code.

What are you trying to achieve here? Shifting or C++ like streams? I don't
believe C++ like stream operators are emulateable within C#. If your class
supports some form of logical shifting you may want to look into making your
class immutable and require the assignment
 
I

Ian Lazarus

Yes, the idea is to duplicate the overloading of << and >> as is often shown
in C++ for file input/output. Based on my _very_ limited knowledge of C#, it
seems that all that is necessary is to overload the operator, which it
permits. Is there some fundamental reason why << and >> shouldn't alter the
object? Who determines what a "correctly" behaving operator is? As long as
it is intuitive to the user, who cares what it does?

file << a << b << c; is certainly more convenient then file.Write(a);
file.Write(b); file.Write(c);

Thanks
 
D

Daniel O'Connell [C# MVP]

Ian Lazarus said:
Yes, the idea is to duplicate the overloading of << and >> as is often
shown in C++ for file input/output. Based on my _very_ limited knowledge
of C#, it seems that all that is necessary is to overload the operator,
which it permits. Is there some fundamental reason why << and >> shouldn't
alter the object? Who determines what a "correctly" behaving operator is?
As long as it is intuitive to the user, who cares what it does?

There is no fundamental reason, but there are two pretty effective ones.
One is that the language is designed to disallow operators that do not
result in reassignments. Thus, operators that make changes to an object must
still be used in an assignment.

The second is that people expect

if ((b<<a) !=0)
{

}

would not change either a or b. By making an operator change one of the
operands instead of returning a new one, you create non-obvious behaviour
and increase the risk of bugs in your code.

No operator is expected to change the value of an operand. ++, --, and the
<op>= style operators are the closest thing to an exception, and in each of
those cases, the operators are actually a combination of operator and
assignment and are expected to be result in a variables value change, not an
operand itself nessecerily changing.

Again, nothing requires that operators do not change any of their operands,
I just don't think its a good idea nor do I think that the language
particularly lends itself to doing so.
file << a << b << c; is certainly more convenient then file.Write(a);
file.Write(b); file.Write(c);

Actually, I think it was one of the worst ideas in C++ ever, but thats a
different matter(makes << mean to many different things). It is convient to
a C++ user, but its utterly unclear to someone who has never used C++, and
it looks like a bit shift, not a file write.
 
J

Jon Skeet [C# MVP]

Ian Lazarus said:
Yes, the idea is to duplicate the overloading of << and >> as is often shown
in C++ for file input/output. Based on my _very_ limited knowledge of C#, it
seems that all that is necessary is to overload the operator, which it
permits. Is there some fundamental reason why << and >> shouldn't alter the
object? Who determines what a "correctly" behaving operator is? As long as
it is intuitive to the user, who cares what it does?

file << a << b << c; is certainly more convenient then file.Write(a);
file.Write(b); file.Write(c);

It's also less readable to those who aren't familiar with C++, of
course.

How positive are you that no-one who is only familiar with .NET will
read your code?
 
J

Jay B. Harlow [MVP - Outlook]

Ian,
As long as it is intuitive to the user, who cares what it does?
Intuitive to who? You as the initial developer? Or the many developers who
inherit your code?

IMHO intuitively << does a logical shift, not a write to file! As the
guidelines below state, its "immediately obvious" what the intent of the
shift operator is. Intuitively "Write" does a write to file.

See the "Operator Overloading Usage Guidelines" in the "Design Guidelines
for Class Library Developers"
http://msdn.microsoft.com/library/d...l/cpconOperatorOverloadingUsageGuidelines.asp

Hope this helps
Jay
 

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

Top