Missing C# operator = workaround

Hi,

I am trying to create a struct that feels like a primative such as Int32, and I want it to be usable with Int32 so that the following is supported:

Int32 intVal = 3;

MyInt32 myIntVal = intVal; // don't know how to get this to work.

intVal = myIntVal; // this works via cast operator.

Here is my definition of MyInt32:

public struct MyInt32

{

static Int32 implicit operator(MyInt32 myInt)

{

return ...;

}

}

If I could overload operator = then I would be able to provide the ability to assign an Int32 value to an MyInt32 value, but without it I am at a loss. Any ideas



Answer this question

Missing C# operator = workaround

  • Frank Loizzi

    I think that it is probably a bad idea to make a struct that is obviously more than just a normal Int32, act and behave like one. If I was a new developer to this code base, it would be very unexpected (implicit and explicit operator overloads should really only be used by structs designed to be primitive types).

    I'm a little unsure as to what you are trying to achieve. By what you've written, it sounds like that each MyInt32 is reading its own value from a database. If so, this is probably a bad idea, it won't scale, and it seems to me that the MyInt32 struct knows/does too much.

    If I have misinterpreted what you're trying to do, can you post a little code sample exactly what you are trying to achieve (it doesn't actually have to compile/work)



  • sana234

    Thanks David for the reply. I tried that and the result is a separate value object that then gets assigned by C# without my having the ability to intercept the asignment.



    public static implicit operator MyInt32 (Int32 value)
    {
    return new MyInt32(value);
    }

    Int32 builtInInt = 3;

    MyInt32 myInt = builtInInt;

    On the second line the cast operator creates a copy that can only know about the value, but what I should have shared is that the original MyUInt32 instance has other state that is used to get/set the value from an underlying DB. The copy lacks this information, so the constructor that recieves the new value cannot perform the update. There is also a member by member copying that is performed invisibly by C# on the second line, but there does not seem to be a way to intercept that event (as there is no overloading of operator =).

    I'm just trying to make DB value access look and feel like normal access, which I could do with a property, but then each property has the access code, which makes it more verbose and harder to add to a class than a simple struct. Is there some other technique I should be considering

    Thanks!


  • atul_v

    Lenny,

    You have to declare another implicit cast between Int32 and your struct:



    public static implicit operator MyInt32 (Int32 value)
    {
    [..]
    }



  • Recycled Gardens

    Thanks again David.

    MyInt32 is trying to read its own value from a database. Not sure why you say it won't scale though. I'm sure that is because I'm new to C# and probably don't understand structs fully. I'm an experienced C++ and Java developer, and struct looked like the closest thing I could find to an embedded class in C++ (non existent in Java). I did not see that directly stated in the book I bought or the on-line references I have been using, only that structs (value objects) are stored on the stack, not on the heap, but nonetheless was hoping that if a struct is made a data member of a class that it was not a reference variable like in Java, but rather a direct part of instances of the enclosing class like in C++. Is that not true

    I'm endevering to allow C# developers to define via C# in as C# natural way as possible classes in a DB schema, and then provide access to the state of those objects resident in the DB in a performant manner. The C# definition will be used to create the schema using reflection, and then used to create/access DB objects at runtime. At the point these data member structs (my attempt at embedded) are used, the underlying object's state is already loaded into a managed C++ object, and can be accessed by knowing the C++ object and the offset of the data member within it. This is the "extra" information in MyInt I was talking about. I have come up with two ways of doing this, a property and an "embeded" data member.

    For a C# member to access the C++ object member value twothings need to be known: the C++ object and the member offset. Since the offset is constant, it is discoved once via a static data member of the C# class; e.g. for the age member of a Person class:

    static private AttrDes smAgeAttr = Storable.getAttr("Person", "age");

    The smAgeAttr static is initialized once per Person class use and contains within it the offset.

    My first attempt was to use a propery as such:

    public UInt32 age

    {

    get

    {

    return getUInt32(smAgeAttr);

    }

    set

    {

    setUInt32(smAgeAttr, value);

    }

    }

    Here the Person object inherites from a base class in a managed C++ layer that knows the address of the C++ object, and the getUInt32 and setUInt32 methods belong to that base.

    The problem with this approach is that I did not like the prospect of folks having to insert this property code for each schema data member. So I thought that something akin to a C++ embedded class would provide greater ease of use with a little (hopefully acceptable) overhead. So instead of the property they would add to the Person class somewhat simpler code:

    private MyUInt32 mAge;

    Then in the Person constructor:

    mAge = new MyUInt32(this, smAgeAttr);

    After which I wanted to have mAge appear to be a normal UInt32, thus the desire for the ability to overload operator =. Thus MyUint32 needs to run getUInt32 and setUInt32 at the right times just as the property does. A cast from MyUInt32 to UInt32 provides the hook for calling get, but I can't figure out where to put the set without an overloaded operator =.


  • Missing C# operator = workaround