zzfima zzfima - 23 days ago 5
C# Question

Why C# compiler generate error, even if using Attribute "SpecialName"

i write code:

using System.Runtime.CompilerServices;

namespace ConsoleApplication21
{
class Program
{
static void Main(string[] args)
{
int i = new MyClass1() - new MyClass1();
int j = new MyClass1() + new MyClass1();
}
}

public class MyClass1
{
public static int operator -(MyClass1 i, MyClass1 j)
{
return 5;
}

[SpecialName]
public static int op_Addition(MyClass1 i, MyClass1 j)
{
return 5;
}
}
}


compile time error:


Error 1 Operator '+' cannot be applied to operands of type
'ConsoleApplication21.MyClass1' and 'ConsoleApplication21.MyClass1'


So, c# compiler did not like line "int j = new MyClass1() + new MyClass1();"
When i open ILDASM, i got same code of operator overloadings:

Method #1 (06000003)
-------------------------------------------------------
MethodName: op_Subtraction (06000003)
Flags : [Public] [Static] [HideBySig] [ReuseSlot] [SpecialName] (00000896)
RVA : 0x00002078
ImplFlags : [IL] [Managed] (00000000)
CallCnvntn: [DEFAULT]
ReturnType: I4
2 Arguments
Argument #1: Class ConsoleApplication21.MyClass1
Argument #2: Class ConsoleApplication21.MyClass1
2 Parameters
(1) ParamToken : (08000002) Name : i flags: [none] (00000000)
(2) ParamToken : (08000003) Name : j flags: [none] (00000000)

Method #2 (06000004)
-------------------------------------------------------
MethodName: op_Addition (06000004)
Flags : [Public] [Static] [HideBySig] [ReuseSlot] [SpecialName] (00000896)
RVA : 0x0000208c
ImplFlags : [IL] [Managed] (00000000)
CallCnvntn: [DEFAULT]
ReturnType: I4
2 Arguments
Argument #1: Class ConsoleApplication21.MyClass1
Argument #2: Class ConsoleApplication21.MyClass1
2 Parameters
(1) ParamToken : (08000004) Name : i flags: [none] (00000000)
(2) ParamToken : (08000005) Name : j flags: [none] (00000000)


So, why C# compiler generates an error?

Really, strange behavior: if i reference the MyClass1 as DLL, it works fine!

enter image description here
Thanks!

Answer

Really, strange behavior: if i reference the MyClass1 as DLL, it works fine!

That explains a lot. The CLR compiles the code into an assembly. Before it does that, it evaluates the code you have without taking the special name signature in consideration. That code gives an compilation error since at that time, there is no matching overload yet. It still has to be embedded and compiled. (It is a chicken or the egg problem)

The compiled assembly can be used from another project, since there the assembly has compiled entirely.