C#模仿覆盖赋值运算符(=)

6 c# operator-overloading variable-assignment

我有一个简单的包装类我有一些问题.

它看起来像这样:

public class Wrapper<T>
{
  private T _value;

  public Wrapper<T>(T value)
  {
    _value = value;
  }

  public static implicit operator Wrapper<T>(T value)
  {
    return new Wrapper<T>(value);
  }

  public static implicit operator T(Wrapper<T> value)
  {
    return value._value;
  }
}
Run Code Online (Sandbox Code Playgroud)

我已经覆盖了T的隐式转换器,因此它的行为几乎就像是T本身的一个实例.

例如

Wrapper<int> foo = 42;
Run Code Online (Sandbox Code Playgroud)

但是,在将一个Wrapper实例分配给另一个时,我遇到了一个小问题,因为我只想分配第二个Wrapper类的值.

所以现在,我必须这样做:

Wrapper<int> foo = 42;
Wrapper<int> bar = (int)foo;
Run Code Online (Sandbox Code Playgroud)

或通过属性公开公开_value.

但是因为这是在一个库中,我不希望用户依赖于记住这个,你们有没有想过我怎么能模仿覆盖赋值运算符?

只更改指针的问题(就像将类实例分配给另一个时一样)是我有一个指向这些Wrapper对象的指针字典,所以我不能让它们一直在改变,因为字典会停止然后匹配.

我可以看看这有点令人困惑,所以如果我留下任何重要的东西,请随时问:-)

Jim*_*hel 5

由于赋值运算符不能过载,因此没有一个真正好的解决方案.正如其他人所指出的那样,使用struct会给你你想要的赋值语义,但是你会遇到价值语义 - 通常不是一件好事.

一种选择是重载构造函数:

public Wrapper(Wrapper<T> w)
{
    _value = w._value;
}
Run Code Online (Sandbox Code Playgroud)

这会导致这种语法:

Wrapper<int> foo = 42;
Wrapper<int> bar = new Wrapper<int>(foo);
Run Code Online (Sandbox Code Playgroud)

虽然比你拥有的更冗长,但它读得更好.

或者你可以添加一个Clone方法(不是ICloneable接口),这样你就可以写:

Wrapper<int> bar = foo.Clone();
Run Code Online (Sandbox Code Playgroud)

你可以获得真正的创造力并使某些操作员超载,使其基本上没有任何作用 不过,我不建议这样做.使用运算符重载来处理这些事情通常会使代码变得模糊并经常中断.


Fly*_*wat 1

如果您查看 Nullable<T>...,它所做的事情与您在这里所做的非常相似,它使用 .Value 属性公开内部值。

只是改变指针(就像将一个类实例分配给另一个类实例时那样)的问题是,我有一个指向这些包装对象的指针字典,所以我不能让它们一直改变,因为字典会停止那么匹配。

我不确定我是否遵循这一点,你到底在字典中存储了什么?因为如果您要存储引用,CLR 将根据需要更新它们。