diff --git a/src/Main/Base/Project/Src/TextEditor/Commands/CodeGenerators/EqualsCodeGenerator.cs b/src/Main/Base/Project/Src/TextEditor/Commands/CodeGenerators/EqualsCodeGenerator.cs
index 727918e94c..7dd627d3a7 100644
--- a/src/Main/Base/Project/Src/TextEditor/Commands/CodeGenerators/EqualsCodeGenerator.cs
+++ b/src/Main/Base/Project/Src/TextEditor/Commands/CodeGenerators/EqualsCodeGenerator.cs
@@ -26,14 +26,30 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
{
TypeReference intReference = new TypeReference("System.Int32");
MethodDeclaration method = new MethodDeclaration("GetHashCode", Modifiers.Public | Modifiers.Override, intReference, null, null);
- Expression expr = CallGetHashCode(new IdentifierExpression(currentClass.Fields[0].Name));
- for (int i = 1; i < currentClass.Fields.Count; i++) {
- IdentifierExpression identifier = new IdentifierExpression(currentClass.Fields[i].Name);
- expr = new BinaryOperatorExpression(expr, BinaryOperatorType.ExclusiveOr,
- CallGetHashCode(identifier));
- }
method.Body = new BlockStatement();
- method.Body.AddChild(new ReturnStatement(expr));
+
+ VariableDeclaration var;
+ var = new VariableDeclaration("hashCode", new PrimitiveExpression(0, "0"), intReference);
+ method.Body.AddChild(new LocalVariableDeclaration(var));
+
+ Expression expr;
+
+ foreach (IField field in currentClass.Fields) {
+ expr = new AssignmentExpression(new IdentifierExpression(var.Name),
+ AssignmentOperatorType.ExclusiveOr,
+ new InvocationExpression(new FieldReferenceExpression(new IdentifierExpression(field.Name), "GetHashCode")));
+ if (IsValueType(field.ReturnType)) {
+ method.Body.AddChild(new ExpressionStatement(expr));
+ } else {
+ method.Body.AddChild(new IfElseStatement(
+ new BinaryOperatorExpression(new IdentifierExpression(field.Name),
+ BinaryOperatorType.ReferenceInequality,
+ new PrimitiveExpression(null, "null")),
+ new ExpressionStatement(expr)
+ ));
+ }
+ }
+ method.Body.AddChild(new ReturnStatement(new IdentifierExpression(var.Name)));
nodes.Add(method);
TypeReference boolReference = new TypeReference("System.Boolean");
@@ -49,14 +65,14 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
expr = new UnaryOperatorExpression(expr, UnaryOperatorType.Not);
method.Body.AddChild(new IfElseStatement(expr, new ReturnStatement(new PrimitiveExpression(false, "false"))));
- expr = new BinaryOperatorExpression(new ThisReferenceExpression(),
- BinaryOperatorType.Equality,
- new IdentifierExpression("obj"));
- method.Body.AddChild(new IfElseStatement(expr, new ReturnStatement(new PrimitiveExpression(true, "true"))));
+// expr = new BinaryOperatorExpression(new ThisReferenceExpression(),
+// BinaryOperatorType.ReferenceEquality,
+// new IdentifierExpression("obj"));
+// method.Body.AddChild(new IfElseStatement(expr, new ReturnStatement(new PrimitiveExpression(true, "true"))));
- VariableDeclaration var = new VariableDeclaration("my" + currentClass.Name,
- new CastExpression(currentType, new IdentifierExpression("obj"), CastType.Cast),
- currentType);
+ var = new VariableDeclaration("my" + currentClass.Name,
+ new CastExpression(currentType, new IdentifierExpression("obj"), CastType.Cast),
+ currentType);
method.Body.AddChild(new LocalVariableDeclaration(var));
expr = TestEquality(var.Name, currentClass.Fields[0]);
@@ -70,16 +86,39 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
nodes.Add(method);
}
- static InvocationExpression CallGetHashCode(Expression expr)
+ static bool IsValueType(IReturnType type)
+ {
+ IClass c = type.GetUnderlyingClass();
+ return c != null && (c.ClassType == Dom.ClassType.Struct || c.ClassType == Dom.ClassType.Enum);
+ }
+
+ static bool CanCompareEqualityWithOperator(IReturnType type)
{
- return new InvocationExpression(new FieldReferenceExpression(expr, "GetHashCode"));
+ // return true for value types except float and double
+ // return false for reference types except string.
+ IClass c = type.GetUnderlyingClass();
+ return c != null
+ && c.FullyQualifiedName != "System.Single"
+ && c.FullyQualifiedName != "System.Double"
+ && (c.ClassType == Dom.ClassType.Struct
+ || c.ClassType == Dom.ClassType.Enum
+ || c.FullyQualifiedName == "System.String");
}
static Expression TestEquality(string other, IField field)
{
- return new BinaryOperatorExpression(new FieldReferenceExpression(new ThisReferenceExpression(), field.Name),
- BinaryOperatorType.Equality,
- new FieldReferenceExpression(new IdentifierExpression(other), field.Name));
+ if (CanCompareEqualityWithOperator(field.ReturnType)) {
+ return new BinaryOperatorExpression(new FieldReferenceExpression(new ThisReferenceExpression(), field.Name),
+ BinaryOperatorType.Equality,
+ new FieldReferenceExpression(new IdentifierExpression(other), field.Name));
+ } else {
+ InvocationExpression ie = new InvocationExpression(
+ new FieldReferenceExpression(new TypeReferenceExpression("System.Object"), "Equals")
+ );
+ ie.Arguments.Add(new FieldReferenceExpression(new ThisReferenceExpression(), field.Name));
+ ie.Arguments.Add(new FieldReferenceExpression(new IdentifierExpression(other), field.Name));
+ return ie;
+ }
}
public override bool IsActive {
diff --git a/src/Setup/Files.wxs b/src/Setup/Files.wxs
index cfb1c61658..ebcd2163a5 100644
--- a/src/Setup/Files.wxs
+++ b/src/Setup/Files.wxs
@@ -73,7 +73,7 @@
-
+
@@ -94,7 +94,7 @@
-
+
@@ -1253,4 +1253,4 @@
-
\ No newline at end of file
+