简体   繁体   中英

Why implicit operator has to be static?

I have a class named FloatPlugIn . I want user to be able to do things like

FloatPlugIn x = new FloatPlugIn();
x.Minimum = -100;
x.Maximum = 100;

float y = 123;
x = y;

That is why I decided to add implicit operator to my class

public static implicit operator FloatPlugIn(float p)
{
    return new FloatPlugIn() { Default = p };
}

Problem is that implicit operator has to be static that is why during conversion new instance of my class is created. As a result I am loosing all the information that was located inside of "old" instance.

Is there a way to fix that? I want float value to be applied to existing instance, not to completely replace it.

I don't think you're understanding what conversion does - it's not casting - it must create a new instance. It only makes sense to make it non-static if it were only updating the existing instance.

I think it's better in this case if you either use x.Default = y; or if you create a constructor that takes the float like this:

// Constructor
public FloatPlugIn(float p)
{
    Default = p;
}

Usage:

float y = 123;
FloatPlugIn x = new FloatPlugIn(y);

The semantics of the assignment operator requires that behavior. In fact:

The assignment operator (=) stores the value of its right-hand operand in the storage location, property, or indexer denoted by its left-hand operand and returns the value as its result. The operands must be of the same type (or the right-hand operand must be implicitly convertible to the type of the left-hand operand).

It is not the purpose of the implicit conversion operator to modify a destination value—note that there may not be any such destination value, such as in case you pass the value to a parameter of a method.

I want float value to be added to existing instance, not to completely replace it.

If you want an addition (in whatever specific sense that would mean in your case), consider overriding the addition + operator, which in turn has effect on the addition assignment += operator . However, you won't eliminate the creation of a new FloatPlugIn instance anyway.

Consider you'd have the following method in FloatPlugIn , which would modify an existing instance:

public void Add(float f)
{
    // do whatever 'addition' means in your case
}

Then the + operator should work like this:

public static FloatPlugIn operator +(FloatPlugIn a, float b)
{
    FloatPlugIn result = a.Clone(); // here Clone() denotes any custom method that creates a copy of that instance
    result.Add(b);
    return b;
}

In your code, the following would work then:

FloatPlugIn x = new FloatPlugIn();
x.Minimum = -100;
x.Maximum = 100;

float y = 123;
x += y; // a new instance is created, but the 'addition' logic is preserved

Also, the same will intuitively work in case of passing a value to a method call:

ProcessMyFloatPlugin(x + 123.0f);

You can see that it is a really good idea to create a new instance of FloatPlugIn as a result of an operator. Otherwise, an in-place modification of x would be, in fact, a nasty side-effect, completely unexpected by any other developer. Note that if performance (avoiding dynamic memory allocations) is a concern, consider using struct s.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM