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

C# 为什么隐式运算符必须是静态的?,c#,C#,我有一个名为FloatPlugIn的类。我希望用户能够像这样做 FloatPlugIn x = new FloatPlugIn(); x.Minimum = -100; x.Maximum = 100; float y = 123; x = y; 这就是为什么我决定将隐式操作符添加到我的类中 public static implicit operator FloatPlugIn(float p) { return new FloatPlugIn() { Default = p };

我有一个名为
FloatPlugIn
的类。我希望用户能够像这样做

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

float y = 123;
x = y;
这就是为什么我决定将
隐式操作符添加到我的类中

public static implicit operator FloatPlugIn(float p)
{
    return new FloatPlugIn() { Default = p };
}
问题是隐式运算符必须是静态的,这就是为什么在转换期间创建我的类的新实例的原因。因此,我丢失了位于“旧”实例内部的所有信息


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

我认为在这种情况下,如果使用
x.Default=y或如果您创建一个构造函数,该构造函数接受如下浮点值:

// Constructor
public FloatPlugIn(float p)
{
    Default = p;
}
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
实例

假设您在
FloatPlugIn
中有以下方法,该方法将修改现有实例:

public void Add(float f)
{
    // do whatever 'addition' means in your case
}
然后,
+
操作符应如下工作:

// Constructor
public FloatPlugIn(float p)
{
    Default = p;
}
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
的就地修改实际上将是一个令人讨厌的副作用,任何其他开发人员都无法预料。请注意,如果性能(避免动态内存分配)是一个问题,请考虑使用<代码>结构> <代码> S.< /P> < P>我不认为你理解转换是什么——它不是铸造-它必须创建一个新的实例。只有在仅更新现有实例时,才有必要将其设置为非静态。

不能使用赋值运算符“添加”。C#语义与您作为一个无辜的开发人员阅读此代码时所期望的情况相匹配,而您的意图是颠覆它们。为什么不重载
+
呢?我希望将浮点值添加到现有实例中。。。那么,一个
Add
方法不是更合适吗?做
x.Default=y?听起来您确实想在现有实例上设置属性。确切地说。赋值会分配一个完全独立的实例,因此您当然会丢失该“旧”实例的所有信息。因此,您不需要指定,而是需要修改。我相信您误解了OP中“添加”的含义。他并不是在建议一个数学加法运算,而是要求用现有实例以某种方式组合浮点值。@Enigmativity:运算符重载的“美妙之处”(有些人会称之为诅咒)在于你不受数学的约束
Foo operator+(Foo-Foo,float p)
基本上可以做任何你想做的事情——它甚至可以在修改后返回
Foo
,尽管这破坏了语义,以至于你可能会在使用它时遇到麻烦。这并不是说一个简单、显式的实例方法不可能是这里更合适的解决方案——这取决于
FloatPlugIn
是什么类型的东西,以及“添加”float是否有意义。@Enigmativity我不这么认为。无论OP的“加法”是什么意思,都可以。
+
运算符在表示常识中的“加法”时效果很好。现在请参阅我的更新答案,其中提供了一个具体示例。如果现在清楚的话,那么欢迎联合国投反对票:)对不起,这并没有回答我的问题。我更喜欢x.Default=yi如果你仔细看,你会发现x.Default=y是我答案中的第一个选择:-)对:)但我希望用户能够像对待普通浮点一样对待x变量,而x内部仍然拥有一些额外的信息。