我被C#中一个奇怪的"不对称"所打击,我真的不明白.请参阅以下代码:
using System;
using System.Diagnostics;
namespace EqualsExperiment
{
class Program
{
static void Main(string[] args)
{
object apple = "apple";
object orange = string.Format("{0}{1}", "ap", "ple");
Console.WriteLine("1");
Debug.Assert(apple.Equals(orange));
Console.WriteLine("2");
Debug.Assert(apple == orange);
Console.WriteLine("3");
}
}
}
Run Code Online (Sandbox Code Playgroud)
对于所有的.NET大师来说,这可能是显而易见的,但第二个断言失败了.
在Java中,我了解到==是这里名为Object.ReferenceEquals的同义词.在C#中,我认为Object.operator ==使用Object.Equals,它是虚拟的,因此它在System.String类中被覆盖.
有人可以解释,为什么第二个断言在C#中失败?我的哪些假设不好?
可以预料,即使字符串是不可变的,Scala中的java.lang.String对象的值相等和引用相等也不相同.这意味着val即使字符串相同,两个字符串保持也不应该是引用相等的.但这是我在2.9.1.final REPL中得到的:
scala> val s1 = "a"; val s2 = "a"
s1: java.lang.String = a
s2: java.lang.String = a
scala> s1 eq s2
res0: Boolean = true
Run Code Online (Sandbox Code Playgroud)
知道为什么结果不是false吗?相同的实验List("a")而不是"a"按预期工作.该eq方法在AnyRef中标记为final .是否有专门针对String或编译魔术java.lang.String?
我正在 Mono 中创建一个 Uri 对象(在 unix 系统下),这非常简单(就像在 VStudio/Windows 中一样):new Uri(" http://my.url_here.com/ ")。然后我创建另一个使用 Uri 的系统对象:HttpSelfHostConfiguration()。
在 HttpSelfHostConfiguration 的源代码中,接收到的 Uri 将使用以下 if 语句进行验证(在 Mono 源中检查):
if (!ReferenceEquals(baseAddress.Scheme, Uri.UriSchemeHttp) && !ReferenceEquals(baseAddress.Scheme, Uri.UriSchemeHttps))
{
throw Error.ArgumentUriNotHttpOrHttpsScheme("baseAddress", baseAddress);
}
Run Code Online (Sandbox Code Playgroud)
并且“if”失败,因为“ReferenceEquals(baseAddress.Scheme, Uri.UriSchemeHttp)”返回false,意味着对于Mono(在Unix中运行)baseAddress.Scheme不等于Uri.UriSchemeHttp。
请注意,在 Mono(Unix) 中已确认调试: baseAddress.Scheme = "http" 和 Uri.UriSchemeHttp = "http"。
在 VStudio 下,这很完美。
任何人都可以帮助我理解 ReferenceEqual 在 Mono(Unix) 下是如何工作的,最重要的是,我如何在 Mono 中创建一个有效的 Uri 并通过上面的 if 语句进行验证?
多谢
在约书亚布洛赫的有效JAVA中,当我读到关于静态工厂方法时,有一个声明如下
静态工厂方法从重复调用返回同一对象的能力允许类在任何时候保持对存在的实例的严格控制.执行此操作的类称为实例控制.编写实例控制类有几个原因.实例控制允许类保证它是单例(第3项)或不可实例化(第4项).此外,它允许不可变类(第15项)保证不存在两个相等的实例:a.equals(b)当且仅当a == b时.如果一个类提供了这种保证,那么它的客户端可以使用==运算符而不是equals(Object)方法,这可以提高性能.枚举类型(第30项)提供此保证.
为了研究==运算符如何带来性能改进,我得看看 String.java
我看到了这个片段
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
通过性能提升,他的意思是什么?它如何带来性能提升.
他的意思是说以下内容
如果每个类都可以确保a.equals(b)当且仅当a == b时,这意味着它带来间接要求,即不能有对象引用2个不同的存储空间并且仍然保持相同的数据,即内存浪费.如果它们拥有相同的数据,则它们是同一个对象.这就是它们指向相同的内存位置.
我在这个推论中是对的吗?
如果我错了你可以指导我理解这个吗?
string s1 = "abc";
string s2 = "ab";
string s3 = s2 + "c";
Console.WriteLine(string.IsInterned(s3)); // abc
Console.WriteLine(String.ReferenceEquals(s1, s3)); // False
Run Code Online (Sandbox Code Playgroud)
我只是不明白为什么s3实习,但是ReferenceEquals是假的.
他们在实习池中有两份副本吗?
提前致谢.
我有一个实现IEquatable <>的类A,使用它的字段(比如Ab和Ac)来实现/重写Equals()并覆盖GetHashCode(),并且99%的时候一切正常.A类是层次结构(B类,C类)的一部分,它们都从接口D继承; 它们都可以一起存储在字典中,因此当它们都带有自己的默认Equals()/ GetHashCode()时很方便.
然而,在构建AI时,有时需要做一些工作来获得Ab和Ac的值; 当发生这种情况时,我想存储对正在构建的实例的引用.在这种情况下,我不想使用A提供的默认Equals()/ GetHashCode()覆盖.因此,我正在考虑实现一个ReferenceEqualityComparer,这意味着强制使用Object的Equals()/ GetHashCode() :
private class ReferenceEqualityComparer<T> : IEqualityComparer<T>
{
#region IEqualityComparer<T> Members
public bool Equals(T x, T y)
{
return System.Object.ReferenceEquals(x, y);
}
public int GetHashCode(T obj)
{
// what goes here? I want to do something like System.Object.GetHashCode(obj);
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
问题是,由于A重写了Object.GetHashCode(),我如何(在A之外)调用Object.GetHashCode()作为A的实例?
当然,一种方法是A不实现IEquatable <>并且始终为我创建的任何字典提供IEqualityComparer <>,但我希望得到不同的答案.
谢谢
我试图了解OCaml中物理相等运算符(Pervasives.(==)和Pervasives.(!=))的含义.
语言手册说表达式""是"常量",而不是"表达式":
6.5常数
constant :: == ... string-literal
但是我找不到任何表明常量是单独/预先评估或合并的,并且REPL表明可变字符串值(谢天谢地)没有合并.
(* a *) "" == "";; (* false *)
(* b *) "foo" == "foo";; (* false *)
(* c *) "" == String.copy "";; (* false *)
(* d *) () == ();; (* true *)
(* e *) (42, -42) == (42, -42);; (* false *)
(* f *) ("", 1) == ("", 1);; (* false *)
(* g *) None == None;; …Run Code Online (Sandbox Code Playgroud) 我想要equals()更好地理解这个方法.我见过的所有例子都是这样的:
public class City
{
public boolean equals(Object other)
{
if (other instanceof City && other.getId().equals(this.id))
{
return true;
}
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
该方法必须采用对象而不是城市吗?
例如下面不允许这个?
public class City
{
public boolean equals(City other)
{
if (other == null)
{
return false;
}
return this.id.equals(other.getId());
}
}
Run Code Online (Sandbox Code Playgroud) 请考虑以下我正在审核的代码:
public override bool Equals(object other)
{
return !object.ReferenceEquals(null, this)
&& (object.ReferenceEquals(this, other)
|| ((other is MyType) && this.InternalEquals((MyType)other)));
}
Run Code Online (Sandbox Code Playgroud)
这段代码的第一行引发了我的好奇心.每当this为null时,该方法应返回false.现在我很确定程序员打算用!object.ReferenceEquals(other, null)快捷方式编写null,但是他坚持认为this可以为null.我坚持认为它不能(除非有人使用直接内存操作).我们应该留下吗?
当我们装箱两种值类型(它们是不同的类型但兼容以比较值,例如:int 和 short)并尝试调用 Equals 方法时,即使值相同也会给出 false。
情况1:
int a = 5;
short b = 5;
var ob_a = (object) a;
var ob_b = (object) b;
var result = a == b; // true
var result_for_objects = ob_a.Equals(ob_b); // false
Run Code Online (Sandbox Code Playgroud)
另一方面,当两个值类型相同时,Equals 返回实际值比较结果。
案例2:
int a = 5;
int b = 5;
var ob_a = (object) a;
var ob_b = (object) b;
var result = a == b; // true
var result_for_objects = ob_a.Equals(ob_b); // true
Run Code Online (Sandbox Code Playgroud)
我比较了两种情况的两种反汇编代码,但它是相同的,我找不到任何区别。
var result = a == …Run Code Online (Sandbox Code Playgroud) 在Java中是否可以创建HashMap使用引用相等而不是equals()方法?
referenceequals ×11
c# ×6
equals ×3
java ×3
.net ×2
string ×2
collections ×1
equality ×1
gethashcode ×1
iequatable ×1
mono ×1
null ×1
ocaml ×1
performance ×1
reference ×1
scala ×1
this ×1
unix ×1