Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 可以进行隐式转换吗;突变;它的目标是什么?_C#_Implicit Conversion - Fatal编程技术网

C# 可以进行隐式转换吗;突变;它的目标是什么?

C# 可以进行隐式转换吗;突变;它的目标是什么?,c#,implicit-conversion,C#,Implicit Conversion,我想为C#中的隐式“输入”转换找到一种方法,使其能够变异转换的目标对象,而不是用新对象替换它 场景:我有一个包装器类型ObservableValue,如下所示: public struct ObservableValue { public event EventHandler ValueChanged; public ObservableValue(int value) { mValue = value; // must initial

我想为C#中的隐式“输入”转换找到一种方法,使其能够变异转换的目标对象,而不是用新对象替换它

场景:我有一个包装器类型
ObservableValue
,如下所示:

public struct ObservableValue
{
    public event EventHandler ValueChanged;

    public ObservableValue(int value)
    {
        mValue = value;

        // must initialize all members since this is a struct
        ValueChanged = null;
    }

    public int Value
    {
        get { return mValue; }
        set { if (mValue != value) { mValue = value; RaiseValueChanged(); } }
    }

    public static implicit operator T(ObservableValue value)
    {
        return value.mValue;
    }

    private RaiseValueChanged()
    {
        var handler = ValueChanged;
        if (handler != null) handler(this, EventArgs.Empty);
    }

    private int mValue;
}
正如您所见,该类支持隐式转换为其包装类型,因此我可以编写以下代码:

ObservableValue myValue = new ObservableValue(6);
int result = myValue * 7; // 42
myValue = 42;
我还希望允许隐式输入转换(从包装类型到包装),以便编写以下代码:

ObservableValue myValue = new ObservableValue(6);
int result = myValue * 7; // 42
myValue = 42;
所以我尝试了一个标准的隐式转换操作符:

public static implicit operator ObservableValue(int value)
{
    return new ObservableValue(value);
}
这里的问题是转换创建了一个新的
observeValue
,这意味着
ValueChanged
事件的所有订户现在都将丢失是否有任何方法支持隐式“输入”转换,从而保留现有对象状态?


(这个“场景”可能看起来很奇怪,但我已经对它进行了详细的描述。真正的场景更复杂;关键是当通过隐式转换分配对象时,我的包装器类有其他必须保留的状态。)

一开始,你已经得到了一个带有事件的结构,这一事实是非常可疑的。可变值类型通常不是一个好主意,为了使事件正常工作,它必须改变某些内容(以记录订阅)。此外,您的隐式转换仅来自
int
——它如何“知道”它将使用哪个可观察值?(没有转换的目标-只有源。)最后,使用隐式转换听起来是一个非常糟糕的主意-为什么不设置
属性?@JonSkeet没有外部要求它是一个结构。这里我真正的目标是创建一个helper类,它包装一个类型并提供
ValueChanged
事件。我有几个类包含
string
int
等属性,每个类都必须为其他代码提供一个on change事件。我可以按照您的建议简单地使用
.Value
属性,并跳过转换,但我希望找到一种方法来隐式支持它,使可观察包装器“看起来”就像它的包装原语。有没有更好的办法?我愿意接受任何选择。只需使用
属性即可。它会让你的生活变得越来越简单。避免使用那些试图“聪明”的代码——除了别的以外,即使你能做到这一点,我也会发现它完全令人困惑,因为它违背了所有正常的转换惯例。@JonSkeet谢谢你的建议。我认为这取决于谁的“惯例”;它可能不符合C++背景的人,用来分配操作符和<代码>可变的关键字。对于使用代码的外部人员来说,包装器应该与任何其他原语值一样,只是它有一个内置的on change事件。他们通常(如果我工作做得对的话)不需要关心实现。我现在不情愿地坚持使用
.Value
。再次感谢。任何试图编写.NET代码的人,就像他们使用C++一样,无论如何都会有一段不愉快的时光。不要试图在另一个平台上模仿一个平台的习惯用法——根据我的经验,这永远不会奏效。不要忘记,您永远不会更改
int
本身的值(例如)-您会更改变量的值。这是一个非常显著的区别。