C# 隐性会话与新会话

C# 隐性会话与新会话,c#,implicit-conversion,C#,Implicit Conversion,我有以下课程: public class ChArray { private string m_str; public ChArray(string str) { m_str = (str.Length > m_len ? str.Substring(0, m_len) : str); } public static implicit operator ChArray(string str) { return new ChAr

我有以下课程:

public class ChArray {
    private string m_str;
    public ChArray(string str) {
        m_str = (str.Length > m_len ? str.Substring(0, m_len) : str);
    }
    public static implicit operator ChArray(string str) {
        return new ChArray(str);
    }
}
我正在使用这个类作为字典键。为什么下面的陈述不是等价的?使用new,一切正常,但是使用字符串,我得到一个找不到的键

ChArray LINE_LEN = new ChArray("lineLen");
ChArray LINE_LEN = "lineLen"
隐式操作返回一个新的ChArray,那么为什么这不起作用呢


请注意,我并不是发布完整的类来保持简单。如果我使用新方法,这是可行的。

问题不在这里显示的代码中

问题是,如果要将自定义类的实例用作字典中的键,则需要正确地重载

正如它所说:

[类]的默认比较器将检查它们是否实际上是相同的对象(当然不是)

请注意:

Object.Equals("foo", "foo");   // returns true
但是

这两个功能的正确覆盖将提供正确的结果


这应该起作用:


问题不在这里显示的代码中

问题是,如果要将自定义类的实例用作字典中的键,则需要正确地重载

正如它所说:

[类]的默认比较器将检查它们是否实际上是相同的对象(当然不是)

请注意:

Object.Equals("foo", "foo");   // returns true
但是

这两个功能的正确覆盖将提供正确的结果


这应该起作用:


也许您需要重写类ChArray中的GetHashCode()和Equals()?这些用于比较键。

可能需要重写类ChArray中的GetHashCode()和Equals()?这些用于比较键。

只是对其他答案的添加。我的意思是,问题
使用new,一切正常,但是使用字符串,我找不到密钥。
仍然没有答案

当你使用

var key = new ChArray("lineLen");

dictionary.Add(key, someValue);
var value = dictionary[key];
仍然是同一个对象,因为您没有覆盖
Equals
方法,所以使用了
object.Equals
作为参考比较

当你使用

ChArray key = "lineLen";

dictionary.Add(key, someValue);
var value = dictionary[key];
它仍然必须工作

但如果使用,您将获得
KeyNotFoundException

ChArray key = "lineLen";

dictionary.Add(key, someValue);
var value = dictionary["lineLen"];


只是对另一个答案的补充。我的意思是,问题
使用new,一切正常,但是使用字符串,我找不到密钥。
仍然没有答案

当你使用

var key = new ChArray("lineLen");

dictionary.Add(key, someValue);
var value = dictionary[key];
仍然是同一个对象,因为您没有覆盖
Equals
方法,所以使用了
object.Equals
作为参考比较

当你使用

ChArray key = "lineLen";

dictionary.Add(key, someValue);
var value = dictionary[key];
它仍然必须工作

但如果使用,您将获得
KeyNotFoundException

ChArray key = "lineLen";

dictionary.Add(key, someValue);
var value = dictionary["lineLen"];


你试过调试吗?发布一个compiles@wudzik对当我尝试访问字典时失败。@David我创建了dotnet fiddle,它在没有字典的情况下工作这里是fiddle链接,请显示一个简短但完整的程序。您没有向我们展示如何访问字典,也没有任何重写Equals/GetHashCode的指示。您尝试过调试吗?发布一个compiles@wudzik对当我尝试访问字典时失败。@David我创建了dotnet fiddle,它在没有字典的情况下工作这里是fiddle链接,请显示一个简短但完整的程序。您没有向我们展示如何访问字典,也没有任何覆盖Equals/GetHashCode的指示。默认比较器将检查它们是否实际上是同一个对象(当然不是)。正确重写这两个函数将提供正确的结果。非常感谢,特别是代码示例。出于好奇,为什么它需要两个等号呢?
Equals
的重载使用了
ChArray
(类名后缺少空格)可以检查
p
是否为
null
。实际上,当您有两个重载时,
对象
版本应该是简单的
返回等于(obj作为ChArray),空检查将在特定重载中发生。考虑执行<代码> IEQuabtIs/CODE >,因为您选择了具有此特定的重载。考虑在特定的重载中封类或检查<代码> GETType()= .GETType()/代码>。默认比较器将检查它们是否实际上是同一对象(当然它们不是)。正确重写这两个函数将提供正确的结果。非常感谢,特别是代码示例。出于好奇,为什么它需要两个等号呢?
Equals
的重载使用了
ChArray
(类名后缺少空格)可以检查
p
是否为
null
。实际上,当您有两个重载时,
对象
版本应该是简单的
返回等于(obj作为ChArray),空检查将在特定重载中发生。考虑执行<代码> IEQuabtIs/CODE >,因为您选择了具有此特定的重载。考虑在特定的重载中封类或检查<代码> GETType()= .pGETType()/<代码>。