为什么隐式运算符必须是静态的?

我有一个名为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 };

}

问题是隐式运算符必须是静态的,这就是为什么在转换过程中创建了我的类的新实例的原因。结果,我丢失了位于“旧”实例中的所有信息。


有没有办法解决这个问题?我希望将浮点值应用于现有实例,而不是完全替换它。


烙印99
浏览 142回答 3
3回答

慕妹3146593

我认为您没有理解转换的作用 - 它不是强制转换 - 它必须创建一个新实例。如果仅更新现有实例,则使其非静态才有意义。

慕盖茨4494581

我认为在这种情况下,如果您使用x.Default = y;或创建一个采用浮点数的构造函数会更好:// Constructorpublic FloatPlugIn(float p){    Default = p;}用法:float y = 123;FloatPlugIn x = new FloatPlugIn(y);

慕运维8079593

赋值运算符的语义需要这种行为。实际上:赋值运算符 (=) 将其右侧操作数的值存储在由其左侧操作数表示的存储位置、属性或索引器中,并将该值作为其结果返回。操作数必须是相同的类型(或者右侧操作数必须隐式转换为左侧操作数的类型)。隐式转换运算符的目的不是修改目标值——请注意,可能没有任何此类目标值,例如在将值传递给方法的参数的情况下。我希望将浮点值添加到现有实例中,而不是完全替换它。如果您想要一个加法(在您的情况下意味着任何特定的意义),请考虑覆盖加法+运算符,这反过来又会影响加法赋值+=运算符。但是,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实际上将是一个令人讨厌的副作用,任何其他开发人员都完全出乎意料。请注意,如果性能(避免动态内存分配)是一个问题,请考虑使用structs。
打开App,查看更多内容
随时随地看视频慕课网APP