I have gone to an interview where I was asked to answer a question:
Is operator overriding supported by C#?
I know that operator overloading is supported but I have no idea about overriding a operator. Is it possible?
No, operator overriding is not supported. The term Overriding is used when a method is inherited by a subclass and the subclass overrides it with its own implementation. Operators are all static in C# and cannot be overridden.
Overloading means that another method with the same name but a different signature (arguments) is defined. That's what you can do with operators.
This is extremely important to know when writing operators in C#. The operator is bound at compile time. The effective type which is passed to the operator at runtime is not important at all.
Eg. you write some comparison operator
public static bool operator==(MyClass c1, MyClass c2)
{
//...
}
And have the following code:
object myObj1 = new MyClass();
object myObj2 = new MyClass();
if (myObj1 == myObj2)
//...
object's operator will be called, not your own, because the
arguments are references of type object.
Related
The equal operator and default value of generic type are two handy feature in C#. But we can't easily use them seamlessly. For example, I expect the following code can compile,
public static bool EqualsDefault<T>(T subject){
return subject == default(T);
}
Unfortunately, it'll fail, though there's an counter-intuitive alternative,
public static bool EqualsDefault<T>(T subject){
return object.Equals(subject, default(T));
}
So my question is why C# disallows the first code snippet?
The reason it does not work is that the built-in reference equality operator cannot be applied to value types.
Let's take step back and note that System.Object does not, in fact, define an equality operator ==. The C# language defines a built-in reference equality operator with the signature (see section 7.6.10 of the C# 5 specification):
bool operator ==(object x, object y);
However, there two rules about when it can be applied:
The predefined reference type equality operators require one of the following:
Both operands are a value of a type known to be a reference-type or the literal null. Furthermore, an explicit reference conversion (ยง6.2.4) exists from the type of either operand to the type of the other operand.
One operand is a value of type T where T is a type-parameter and the other operand is the literal null. Furthermore T does not have the value type constraint.
The spec then notes that this means that it is an error to apply the operator to two value types unless the type explicitly defines an equality operator. Since you have no constraints, value types are allowed and neither of the operands is null. Therefore, the built-in equality operator cannot be applied and an error is produced.
To remedy this, you could constrain T be a reference type:
public static bool EqualsDefault<T>(T subject) where T : class {
return subject == default(T);
}
However you do need to be aware that the above is always a reference comparison. The compiler will only invoke the == operator on the most specific applicable type at compile time, which in this case is object.
A better alternative is to use EqualityComparer<T>.Default to prevent boxing of value types:
public static bool EqualsDefault<T>(T subject) {
return EqualityComparer<T>.Default.Equals(subject, default(T));
}
I suppose you could ask why C# was not designed to have a default equality operator that can be applied to value types without boxing. I do not know the full reason, but I suspect that it might be more confusing than it is now to determine which methods you are calling in which situations. I think it would be undesirable if in normal methods the overloaded operator was called but in generic methods another mechanism was used. Although you can argue that can happen now with reference types.
As previously mentioned, the compiler is complaining because T could be anything: reference types or struct.
Hence if you make it explicit with constraint:
public static bool EqualsDefault<T>(T subject) where T : class{
return subject == default(T);
}
It'll not complain anymore. Because now, the compiler knows, it's always going to be reference types.
Apparently, for the second one.
public static bool EqualsDefault<T>(T subject){
return object.Equals(subject, default(T));
}
It works because, all the pre-defined or user-defined types in .net directly or indirectly inherit from object and object implements Equals method.
I recently discovered the wonders of implicit operator overloading in C#. I was wondering, if you have both "ways" of implicit operator overloading, such as:
public static implicit operator FooType(int num)
{
return new FooType(num);
}
public static implicit operator int(FooType fooType)
{
return fooType.IntValue;
}
Is there a name for that design pattern?
Is there a predefined .NET interface that I can use, say ICastable<int>?
Not that I'm aware of.
You might consider implementing IConvertible. (If your class can also be compared to things, you might consider implementing IComparable<T>.)
If it is i have never heard of it
Operators are static constructs and are resolved at compile time. They cannot be part of any interface
If reference type doesn't overload an equality operator ==, then build-in equality operator on Object will be used instead. Why isn't the same true for user-defined structs:
struct A{ }
static void Main(string[] args)
{
A a = new A();
A a1 = new A();
bool equal= (a == a1); //error
}
Namely, doesn't ValueType ( from which all structs derive ) also overload == operator?
How would such a default == operator work? For reference types, comparing adresses is reasonable, but since that check will never be true for two ValueTypes (since if two ValueTypes are in scope then they are guaranteed to have different locations on the stack,) address comparison is pointless.
As the compiler has helpfully pointed out, ValueType very intentionally does not have a default == operator.
Structs probably don't provide a default == operator implementation because, unlike a class instance, a struct has no concept of reference-style identity.
From the guidelines:
Implementing the Equality Operator
(==) on Value Types
In most programming languages there is
no default implementation of the
equality operator (==) for value
types. Therefore, you should overload
== any time equality is meaningful.
You should consider implementing the
Equals method on value types because
the default implementation on
System.ValueType will not perform as
well as your custom implementation.
Implement == any time you override the
Equals method.
However, structs do provide a default Equals Method implementation which will do a memberwise compare using reflection.
Is this valid?
public struct MyStruct
{
public int Foo { get; set; }
public static bool operator ==(MyStruct a, MyStruct b)
{
return a.Equals(b);
}
public static bool operator !=(MyStruct a, MyStruct b)
{
return !a.Equals(b);
}
}
(I know it's slightly inefficient because Object.Equals uses reflection for value types by default. But is it valid?)
I'm asking because ReSharper highlights it and warns me that MyStruct defines operator '==' or operator '!=' but does not provide 'Object.Equals(object o)' and 'Object.GetHashCode()'.
I think this may be interesting.
Valid? Yes. But it doesn't buy you anything.
It's valid, in terms of the fact that it compiles. But it's "invalid" in the sense that it breaks all expectations of users of your class - the framework design guidelines specify that you shouldn't implement functionality that only exists in operator overloads - that such methods should be accessible in other ways. And the standard is that Object.Equals and operator== implement the same functionality.
(Can only find the 1.1 version of the guidelines at the moment):
Provide alternate signatures. Most
languages do not support operator
overloading. For this reason, it is a
CLS requirement for all types that
overload operators to include a
secondary method with an appropriate
domain-specific name that provides the
equivalent functionality. It is a
Common Language Specification (CLS)
requirement to provide this secondary
method. The following example is
CLS-compliant.
This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
Why must C# operator overloads be static?
Why Static keyword before the function signature of all the overloaded operators in C# like:
public static void operator = (Object a, Object b)
When we are doing a = b; then a value will be implicitly passed right. So there is no need of static keyword. It must be like:
public void operator = (Object b)
Is it?
The fact that operators are static allows them to be used in situations where there are null values. It also emphasizes the fact that operators are not applied polymorphically. (They potentially could be applied polymorphically if they weren't static, admittedly... but overriding would generally be a bad idea anyway IMO.)
(Note that you can't overload the assignment operator in C# anyway.)
Otherwise you would Always need an instance of the Object to perform that. Which you might not have on case a or b is null.