我有一个名为FloatPlugIn
的课程。我希望用户能够执行
FloatPlugIn x = new FloatPlugIn();
x.Minimum = -100;
x.Maximum = 100;
float y = 123;
x = y;
这就是为什么我决定在课堂上添加implicit operator
public static implicit operator FloatPlugIn(float p)
{
return new FloatPlugIn() { Default = p };
}
问题是隐式运算符必须是静态的,这就是为什么在转换期间创建类的新实例的原因。结果,我失去了位于“旧”实例内部的所有信息。
是否可以解决该问题?我希望将float值应用于现有实例,而不是完全替换它。
答案 0 :(得分:1)
我认为您不了解转换的作用-它不是强制转换-它必须创建一个新实例。仅在更新现有实例的情况下,使其变为非静态才有意义。
答案 1 :(得分:0)
在这种情况下,如果您使用x.Default = y;
或创建一个采用如下浮点数的构造函数,则最好:
// Constructor
public FloatPlugIn(float p)
{
Default = p;
}
用法:
float y = 123;
FloatPlugIn x = new FloatPlugIn(y);
答案 2 :(得分:0)
assignment operator的语义要求这种行为。实际上:
赋值运算符(=)将其右操作数的值存储在由其左操作数表示的存储位置,属性或索引器中,并返回该值作为其结果。操作数必须具有相同的类型(或者右侧操作数必须隐式转换为左侧操作数的类型。)
修改目标值并不是隐式转换运算符的目的-请注意,可能没有任何这样的目标值,例如如果您通过方法参数的值。
我希望将float值添加到现有实例中,而不是完全替换它。
如果您要添加 (在您的情况下,无论是哪种特定含义),请考虑覆盖加法+
运算符,这反过来会影响{{3} }。但是,无论如何您都不会消除创建新的FloatPlugIn
实例的情况。
请考虑在FloatPlugIn
中使用以下方法,该方法将修改现有实例:
public void Add(float f)
{
// do whatever 'addition' means in your case
}
然后+
运算符应像这样工作:
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;
}
在您的代码中,以下代码将起作用:
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
此外,在将值传递给方法调用的情况下,同样可以直观地工作:
ProcessMyFloatPlugin(x + 123.0f);
您会发现,由于操作员的缘故,创建一个FloatPlugIn
的新实例是一个非常好的主意。否则,x
的就地修改实际上是一个讨厌的副作用,任何其他开发人员都完全无法预料。请注意,如果您担心性能(避免动态内存分配),请考虑使用struct
。