[Mono-list] Question about C#

Jonathan Pryor jonpryor@vt.edu
09 Sep 2002 22:55:14 -0400


--=-VjfgrioVIKHv/b0JQ6gG
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

On Mon, 2002-09-09 at 22:15, Ricardo Kirkner wrote:

    I am sorry to bother the list with this question, but I could not
    find a satisfying answer anywhere.
     
    My question regards overloading operators. As far as I know, if you
    want to overload some operator, it must be public and static.
     
    1. I dont understand why this have to be that way

I would guess that the `static' requirement is for language
simplification -- there is only one (consistent) way for operators to be
expressed.  In C++, some operators must be global (read: operator<<,
operator>>).  C# doesn't have global scope, so class-static is the
closest equivalent.  Since some operators would need to be class-static,
it was probably more consistent to just require that they all be
class-static.  That's my best guess, anyway.

I have no idea why  `public' is required.

    2. If I want to overload the ++ operator in a class that I dont want
    to be public, but internal or private, how can I prevent someone
    from accessing a method (the ++ operator) that has been defined
    public? 

Question to ponder: how will they access the public method if they can't
access the class in the first place?  Consider methods that must be
public, such as Object.ToString().  Is it a problem that this method is
public, even in your internal classes?  Not usually -- non-internal
users can't access the class, so the existence of a public ToString()
method shouldn't be a problem.  The same should be true of any
operators.

(The answer to the above question of accessing internal classes is
simple, actually: use Reflection and poke around...  Alternatively,
modify the runtime to permit poking on internal data.  It's hard to
protect against the runtime....  However, these ideas are not trivial,
and can probably be ignored most of the time.)

    Another question is:
     
    Since you can not overload the = operator, how can you redefine the
    assignement without using a copy constructor like 
     
        Class1(Class1 c) { /* data and methods */ } 

I've seen two descriptions of how to handle the non-existence of the
assignment operator.  The first is to kludge it by having an `Assign'
method:


    class Foo {
        public void Assign (Test copy) { /* normal operator= code... */
    }
    }
    
    class TestFoo {
        public static void Main () {
            Foo f1 = new Foo ();
            // change f1...
            Foo f2 = new Foo ();
            // Copy f1
            f2.Assign (f1);
        }
    }

The other kludge is to make the objects cloneable, and clone the object
before making changes you want to preserve:


    class Bar : ICloneable {
        public object Clone () { /* clone as appropriate */ return
    MemberwiseClone(); }
    }
    
    class TestBar {
        public static void Main () {
            Bar b1 = new Bar ();
            // change b1...
    
            // Copy b1
            Bar b2 = (Bar) b1.Clone();
        }
    }

However, the real question remains: why do you need an assignment
operator?  Assignment operators are useful in C++ when wrapping
resources, such as memory, files, thread locks, etc., to make sure that
the resource is properly managed (in concert with the copy constructor
and destructor)...  In C#, the garbage collector is used for resource
management, removing (what I've found) the greatest need for the trio of
C++ copy constructor, assignment operator, and destructor.  If you need
something more deterministic, the IDisposable interface/idiom is
appropriate.

I would need to know more about your program to have any idea why you
would need a copy constructor or assignment operator.

    With regards, and hoping someone can give me a hint
     
    Ricardo Kirkner 

Hope some of this helped.

 - Jon


--=-VjfgrioVIKHv/b0JQ6gG
Content-Type: text/html; charset=utf-8

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
<HTML>
<HEAD>
  <META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=UTF-8">
  <META NAME="GENERATOR" CONTENT="GtkHTML/1.0.3">
</HEAD>
<BODY BGCOLOR="#ffffff">
On Mon, 2002-09-09 at 22:15, Ricardo Kirkner wrote:
    <BLOCKQUOTE>
    <FONT COLOR="#737373"><FONT SIZE="2"><I>I am sorry to bother the list with this question, but I could not find a satisfying answer anywhere.</FONT></FONT></I>
    <BR>
    <FONT COLOR="#737373"><FONT SIZE="3"><I>&nbsp;</FONT></FONT></I>
    <BR>
    <FONT COLOR="#737373"><FONT SIZE="2"><I>My question regards overloading operators. As far as I know, if you want to overload some operator, it must be public and static.</FONT></FONT></I>
    <BR>
    <FONT COLOR="#737373"><FONT SIZE="3"><I>&nbsp;</FONT></FONT></I>
    <BR>
    <FONT COLOR="#737373"><FONT SIZE="2"><I>1. I dont understand why this have to be that way</FONT></FONT></I>
    </BLOCKQUOTE>
<FONT SIZE="2">I would guess that the `static' requirement is for language simplification -- there is only one (consistent) way for operators to be expressed.&nbsp; In C++, some operators must be global (read: operator&lt;&lt;, operator&gt;&gt;).&nbsp; C# doesn't have global scope, so class-static is the closest equivalent.&nbsp; Since some operators would need to be class-static, it was probably more consistent to just require that they all be class-static.&nbsp; That's my best guess, anyway.</FONT>
<BR>
<FONT SIZE="2"></FONT>
<BR>
<FONT SIZE="2">I have no idea why&nbsp; `public' is required.</FONT>
    <BLOCKQUOTE>
    <FONT COLOR="#737373"><FONT SIZE="2"><I>2. If I want to overload the ++ operator in a class that I dont want to be public, but internal or private, how can I prevent someone from accessing a method (the ++ operator) that has been defined public?</FONT></FONT></I><FONT COLOR="#737373"><FONT SIZE="3"><I> </FONT></FONT></I>
    </BLOCKQUOTE>
<FONT SIZE="3">Question to ponder: how will they access the public method if they can't access the class in the first place?&nbsp; Consider methods that must be public, such as Object.ToString().&nbsp; Is it a problem that this method is public, even in your internal classes?&nbsp; Not usually -- non-internal users can't access the class, so the existence of a public ToString() method shouldn't be a problem.&nbsp; The same should be true of any operators.</FONT>
<BR>
<FONT SIZE="3"></FONT>
<BR>
<FONT SIZE="3">(The answer to the above question of accessing internal classes is simple, actually: use Reflection and poke around...&nbsp; Alternatively, modify the runtime to permit poking on internal data.&nbsp; It's hard to protect against the runtime....&nbsp; However, these ideas are not trivial, and can probably be ignored most of the time.)</FONT>
    <BLOCKQUOTE>
    <FONT COLOR="#737373"><FONT SIZE="2"><I>Another question is:</FONT></FONT></I>
    <BR>
    <FONT COLOR="#737373"><FONT SIZE="3"><I>&nbsp;</FONT></FONT></I>
    <BR>
    <FONT COLOR="#737373"><FONT SIZE="2"><I>Since you can not overload the = operator, how can you redefine the assignement without using a copy constructor like </FONT></FONT></I>
    <BR>
    <FONT COLOR="#737373"><FONT SIZE="3"><I>&nbsp;</FONT></FONT></I>
    <BR>
    <FONT COLOR="#737373"><FONT SIZE="2"><I>&nbsp;&nbsp;&nbsp; Class1(Class1 c) { /* data and methods */ }</FONT></FONT></I><FONT COLOR="#737373"><FONT SIZE="3"><I> </FONT></FONT></I>
    </BLOCKQUOTE>
<FONT SIZE="3">I've seen two descriptions of how to handle the non-existence of the assignment operator.&nbsp; The first is to kludge it by having an `Assign' method:</FONT>
<BR>
<FONT SIZE="3"></FONT>
    <BLOCKQUOTE>
    <FONT SIZE="3">class Foo {</FONT>
    <BR>
    <FONT SIZE="3">&nbsp;&nbsp;&nbsp; public void Assign (Test copy) { /* normal operator= code... */ }</FONT>
    <BR>
    <FONT SIZE="3">}</FONT>
    <BR>
    <FONT SIZE="3"></FONT>
    <BR>
    <FONT SIZE="3">class TestFoo {</FONT>
    <BR>
    <FONT SIZE="3">&nbsp;&nbsp;&nbsp; public static void Main () {</FONT>
    <BR>
    <FONT SIZE="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Foo f1 = new Foo ();</FONT>
    <BR>
    <FONT SIZE="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // change f1...</FONT>
    <BR>
    <FONT SIZE="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Foo f2 = new Foo ();</FONT>
    <BR>
    <FONT SIZE="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Copy f1</FONT>
    <BR>
    <FONT SIZE="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f2.Assign (f1);</FONT>
    <BR>
    <FONT SIZE="3">&nbsp;&nbsp;&nbsp; }</FONT>
    <BR>
    <FONT SIZE="3">}</FONT>
    </BLOCKQUOTE>
<FONT SIZE="3">The other kludge is to make the objects cloneable, and clone the object before making changes you want to preserve:</FONT>
<BR>
<FONT SIZE="3"></FONT>
    <BLOCKQUOTE>
    <FONT SIZE="3">class Bar : ICloneable {</FONT>
    <BR>
    <FONT SIZE="3">&nbsp;&nbsp;&nbsp; public object Clone () { /* clone as appropriate */ return MemberwiseClone(); }</FONT>
    <BR>
    <FONT SIZE="3">}</FONT>
    <BR>
    <FONT SIZE="3"></FONT>
    <BR>
    <FONT SIZE="3">class TestBar {</FONT>
    <BR>
    <FONT SIZE="3">&nbsp;&nbsp;&nbsp; public static void Main () {</FONT>
    <BR>
    <FONT SIZE="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Bar b1 = new Bar ();</FONT>
    <BR>
    <FONT SIZE="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // change b1...</FONT>
    <BR>
    <FONT SIZE="3"></FONT>
    <BR>
    <FONT SIZE="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Copy b1</FONT>
    <BR>
    <FONT SIZE="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Bar b2 = (Bar) b1.Clone();</FONT>
    <BR>
    <FONT SIZE="3">&nbsp;&nbsp;&nbsp; }</FONT>
    <BR>
    <FONT SIZE="3">}</FONT>
    </BLOCKQUOTE>
<FONT SIZE="3">However, the real question remains: why do you need an assignment operator?&nbsp; Assignment operators are useful in C++ when wrapping resources, such as memory, files, thread locks, etc., to make sure that the resource is properly managed (in concert with the copy constructor and destructor)...&nbsp; In C#, the garbage collector is used for resource management, removing (what I've found) the greatest need for the trio of C++ copy constructor, assignment operator, and destructor.&nbsp; If you need something more deterministic, the IDisposable interface/idiom is appropriate.</FONT>
<BR>
<FONT SIZE="3"></FONT>
<BR>
<FONT SIZE="3">I would need to know more about your program to have any idea why you would need a copy constructor or assignment operator.</FONT>
    <BLOCKQUOTE>
    <FONT COLOR="#737373"><FONT SIZE="2"><I>With regards, and hoping someone can give me a hint</FONT></FONT></I>
    <BR>
    <FONT COLOR="#737373"><FONT SIZE="3"><I>&nbsp;</FONT></FONT></I>
    <BR>
    <FONT COLOR="#737373"><FONT SIZE="2"><I>Ricardo Kirkner</FONT></FONT></I><FONT COLOR="#737373"><FONT SIZE="3"><I> </FONT></FONT></I>
    </BLOCKQUOTE>
Hope some of this helped.
<BR>

<BR>
 - Jon
<BR>

</BODY>
</HTML>

--=-VjfgrioVIKHv/b0JQ6gG--