Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!

like image 785
zzfima Avatar asked Nov 16 '16 14:11

zzfima


People also ask

Why learn C?

Why Learn C? There are an awful lot of programming languages available right now -- everything from the extremely high level (such as Visual Basic) to the low level power of assembly, and a good variety of specialized options in between ( Perl, Ruby, and Python are good choices for many tasks).

Why is the world powered by C?

Many C projects are still started today; there are some good reasons for that. How is the World Powered by C? Despite the prevalence of higher-level languages, C continues to empower the world. The following are some of the systems that are used by millions and are programmed in the C language.

Why do so many programmers use C?

Plus, with C, you get lots of strong opinions mixed with insights that you can understand. As a result of its age and its use as the language of system programming for Unix, C has become something of the lingua franca of programming. C is a great language for expressing common ideas in programming in a way that most people are comfortable with.

What does %C mean in C programming?

While it's an integer, the %c interprets its numeric value as a character value for display. For instance for the character a: If you used %d you'd get an integer, e.g., 97, the internal representation of the character a using %c to display the character ' a ' itself (if using ASCII)


1 Answers

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.

like image 144
Patrick Hofman Avatar answered Nov 13 '22 07:11

Patrick Hofman