LoginSignup
2
1

More than 3 years have passed since last update.

[C#]演算子のオーバーロードとプリミティブ型

Posted at

はじめに

演算子のオーバーロードはop_xxxというメソッドが内部で定義されるようですが、int型などはこのメソッドを持っていません。
ILの仕様と言われればそれまでですが、ILの仕様を熟知していないので、とりあえず実験してみました。
Type.IsPrimitiveと何か関係があるのかなと思い、組み合わせて検証しました。

いい感じの検索ワードが思いつかず検証してみたので、(なんの役に立つのかはわかりませんが、)自分用のメモとして残します。

環境

Windows 10
Visual Studio 2019

参考

プリミティブ型について
https://ufcpp.net/blog/2016/12/tipsprimitives/

検証1

OP.cs
foreach (var t in types) {
    bool haveOverloadOperator = t.GetMethods().Count(x => x.Name.StartsWith("op_")) > 0;
    Console.WriteLine($"{t.Name} : {t.IsPrimitive} : {haveOverloadOperator}");
}
Boolean : True : False
Byte : True : False
SByte : True : False
Int16 : True : False
UInt16 : True : False
Int32 : True : False
UInt32 : True : False
Int64 : True : False
UInt64 : True : False
IntPtr : True : True
UIntPtr : True : True
Char : True : False
Double : True : True
Single : True : True
Decimal : False : True
Object : False : False
String : False : True
DateTime : False : True
TimeSpan : False : True

op_から始まるメソッドを持っているかどうかのチェックですが、Int16などの整数型はメソッドop_で始まるメソッドがないという、少し意外な結果となりました。

検証2

OP.cs
foreach (var t in types) {
    List<MethodInfo> OverloadOperators = t.GetMethods().Where(x => x.Name.StartsWith("op_")).ToList();
    foreach (var m in OverloadOperators) {
        Console.WriteLine($"{t.Name} : {m.Name}");
    }
}
IntPtr : op_Explicit
IntPtr : op_Explicit
IntPtr : op_Explicit
IntPtr : op_Explicit
IntPtr : op_Explicit
IntPtr : op_Explicit
IntPtr : op_Equality
IntPtr : op_Inequality
IntPtr : op_Addition
IntPtr : op_Subtraction
UIntPtr : op_Explicit
UIntPtr : op_Explicit
UIntPtr : op_Explicit
UIntPtr : op_Explicit
UIntPtr : op_Explicit
UIntPtr : op_Explicit
UIntPtr : op_Equality
UIntPtr : op_Inequality
UIntPtr : op_Addition
UIntPtr : op_Subtraction
Double : op_Equality
Double : op_Inequality
Double : op_LessThan
Double : op_GreaterThan
Double : op_LessThanOrEqual
Double : op_GreaterThanOrEqual
Single : op_Equality
Single : op_Inequality
Single : op_LessThan
Single : op_GreaterThan
Single : op_LessThanOrEqual
Single : op_GreaterThanOrEqual
Decimal : op_Implicit
Decimal : op_Implicit
Decimal : op_Implicit
Decimal : op_Implicit
Decimal : op_Implicit
Decimal : op_Implicit
Decimal : op_Implicit
Decimal : op_Implicit
Decimal : op_Implicit
Decimal : op_Explicit
Decimal : op_Explicit
Decimal : op_Explicit
Decimal : op_Explicit
Decimal : op_Explicit
Decimal : op_Explicit
Decimal : op_Explicit
Decimal : op_Explicit
Decimal : op_Explicit
Decimal : op_Explicit
Decimal : op_Explicit
Decimal : op_Explicit
Decimal : op_Explicit
Decimal : op_UnaryPlus
Decimal : op_UnaryNegation
Decimal : op_Increment
Decimal : op_Decrement
Decimal : op_Addition
Decimal : op_Subtraction
Decimal : op_Multiply
Decimal : op_Division
Decimal : op_Modulus
Decimal : op_Equality
Decimal : op_Inequality
Decimal : op_LessThan
Decimal : op_LessThanOrEqual
Decimal : op_GreaterThan
Decimal : op_GreaterThanOrEqual
String : op_Equality
String : op_Inequality
DateTime : op_Addition
DateTime : op_Subtraction
DateTime : op_Subtraction
DateTime : op_Equality
DateTime : op_Inequality
DateTime : op_LessThan
DateTime : op_LessThanOrEqual
DateTime : op_GreaterThan
DateTime : op_GreaterThanOrEqual
TimeSpan : op_UnaryNegation
TimeSpan : op_Subtraction
TimeSpan : op_UnaryPlus
TimeSpan : op_Addition
TimeSpan : op_Equality
TimeSpan : op_Inequality
TimeSpan : op_LessThan
TimeSpan : op_LessThanOrEqual
TimeSpan : op_GreaterThan
TimeSpan : op_GreaterThanOrEqual

列挙してみると、キャストも含まれていました。。。

doubleやstringに、足し算を意味する"op_Addition"がありません。
整数や浮動小数点数はオーバーロードではなく、コンパイラがILの専用命令に変換しているからop_Additionは不要のようです。
また、参考のリンク先によるとstringの+は文字列連結のconcatに変換されるらしいので、オーバーロードとして定義されていません。

追伸

ここまでくれば、ILの仕様もしくはコンパイル後のILを覗いてみればいいような気がします。
機会があればILを見てみたいと思います。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1