.NET Framework における System.String について
今年に入って初めて .NET Framework にまともに触れるようになってきたのでまだまだ勉強中です。
趣味で触るのはC#、仕事で触るのはVB.NETって感じです。
さて、だいたいどの解説サイトを見ても「C#もVB.NETもできることは同じ」というような解釈になってます。
ただ、System.String
が言語によって扱いが異なる気がしています。
あるとき、VB.NETでNullable(Of String)
と書いたときに静的エラーが出力されました。
妙だと思い調べてみると、System.String
は参照型であるというのです。
基本的な型のうち int, double, byte, char などは値型ですが、
string は「値型のように振る舞う参照型」であるというような記述を見ました。
参照型であるということは null を代入できるのか。
と思い、以下のコードを書きました。
C#
public class Program { public static void Main(string[] args) { string string1 = null; string string2 = ""; string string3 = string.Empty; Console.WriteLine("1:{0}", string1 ?? "string1 is null"); Console.WriteLine("2:{0}", string2 ?? "string2 is null"); Console.WriteLine("3:{0}", string3 ?? "string3 is null"); Console.WriteLine(string1 == string2); // null == "" Console.WriteLine(string2 == string3); // "" == string.Empty Console.WriteLine(string3 == string1); // string.Empty == null } }
VB.NET
Public Module Program Public Sub Main(args() As string) Dim string1 As String = Nothing Dim string2 As String = "" Dim string3 As String = String.Empty Console.WriteLine("1:{0}", If(string1, "string1 is Nothing")) Console.WriteLine("2:{0}", If(string2, "string2 is Nothing")) Console.WriteLine("3:{0}", If(string3, "string3 is Nothing")) Console.WriteLine(string1 = string2) ' Nothing = "" Console.WriteLine(string2 = string3) ' "" = String.Empty Console.WriteLine(string3 = string1) ' String.Empty = Nothing End Sub End Module
動作デモ*1
C# : http://rextester.com/ELTMU58022 VB.NET : http://rextester.com/IRCW50181
と、ここまで来て二つの言語間で結果が違ったことに気づきました。
これ、 ""
と String.Empty
はエイリアスの関係なので言うまでもなく同じものです。
ですから、比較したときにtrue
になるのは当然だと思います。
でも、
string string1 = null; string string2 = ""; Console.WriteLine(string1 == string2); // ==> false
Dim string1 As String = Nothing Dim string2 As String = "" Console.WriteLine(string1 = string2) ' ==> True
なのです。
VB.NETではデフォルトでOption Strict Off
であるため暗黙の型変換が行われたのかと思い、Option Strict On
を記述するも変わらず。
ちなみに、
Dim string1 As String = Nothing Dim string2 As String = "" Console.WriteLine(string2.Equals(string1)) ' ==> False
でした。
この挙動について、このエントリを書いている途中まではSystem.String
の特殊性によるものかと思っていましたが、書いている途中でそれぞれの言語の等価演算子の振る舞いの違いによるものかも?ともちょっと思っています。
どうなんですかね、これ。
何とも尻切れトンボ感あるエントリになってしまいましたが、この辺で。
追記 (2014/11/11 1:21)
どうやら、やはり等価演算子自体が違う振る舞いをするようです。
@htsign ちょい前のやつ、気になってil覗いてみたけど、演算子の実体が違うみたいやで。
— michi (@michi1129) 2014, 11月 10
*1:rextester.comは鯖が落ちていることが稀によくある