泥庭

2011年4月20日

配列の共変性と可変引数

Filed under: .NET — タグ: — yone64 @ 1:20 AM

C#の変数には共変性があります。そのため、stringの配列はそのままobjectの配列に代入することが出来ます。

var strArray = new string[] { "1", "2", "3" };
object[] objArray1 = strArray;

ただし、値型の配列には共変性がないため↓のコードはコンパイルエラーとなります。

var intArray = new[] { 1, 2, 3 };
// 値型は共変性がないので、↓はコンパイルエラー
object[] objArray2 = intArray;

さて、ここに可変引数をとるメソッドとその呼び出しがあります。

static void Main(string[] args)
{
    var obj = new Program();
    obj.Hoge(new[] { 1, 2, 3 });
    Console.WriteLine("");
    obj.Hoge(new[] { "1", "2", "3" });
}

private void Hoge(params object[] args)
{
    Console.WriteLine("Length:" + args.Length);
    Array.ForEach(args, o => Console.WriteLine(o.GetType()));
}

一見同じように見えますが(見えない?)、前述の共変性の有無が絡んでくるため、前者は長さが1の配列、後者は長さが3の配列になります。実行結果は↓の通り。

Length:1
System.Int32[]

Length:3
System.String
System.String
System.String

で、なぜこんなことを調べたかというと、UnitTestではまったからです。

private void Hoge(string[] args)
{
}

↑な感じのprivateメソッドをテストするために、↓なテストコードを書くとテスト実行中にエラーが発生します。

/// <summary>
///Hoge のテスト
///</summary>
[TestMethod()]
public void HogeTest()
{
    PrivateObject po = new PrivateObject(new Program());
    po.Invoke("Hoge", new[] { "aa", "bb" });
}

正しくは、↓とする必要があります。配列の共変性のために、異なる引数のメソッドを探しに行ってしまうためですね。

/// <summary>
///Hoge のテスト
///</summary>
[TestMethod()]
public void HogeTest()
{
    PrivateObject po = new PrivateObject(new Program());
    po.Invoke("Hoge", new object[] { new[] { "aa", "bb" } });
}
広告

コメントする »

まだコメントはありません。

RSS feed for comments on this post. TrackBack URI

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

WordPress.com で無料サイトやブログを作成.

%d人のブロガーが「いいね」をつけました。