skysan's programming notebook

コーディングして思ったことなどを気ままに

参照型の引数が ref だった時の対応

事の始まり

とあるSDKのメソッドに以下のようなものがあり、解決策に悩んだので記録しておきます。
名称などは変更しています。
ここでは、メソッドの引数として渡せるのはOption1クラス、Option2クラスのオブジェクトもしくはnullです。
尚、Option1クラスとOption2クラスは継承関係はありません。

/// <summary>引数に渡されたオブジェクトを元に何か処理をする</summary>
/// <param name="option">Option1, Option2のオブジェクトもしくはnull</param>
/// <return>エラーコード</return>
int api_doSomthing(ref object option);

エラー:参照型の参照渡しでキャストエラー?

C#ではすべてのClassはobjectを継承しているので、そのまま引数に代入できると考えました。 しかし、インスタンスを引数に代入しようとすると、コンパイルエラーになります。

// 引数に渡すオブジェクト
var option1 = new Option1();
int errCode = api_doSomthing(ref option1); //エラー 'ref Option1' から 'ref object' に変換できません。

原因

引数にrefが付いているため、参照型の参照渡しとなり、型に互換性がなくためだそうです。(原因の深掘りはしてません)
参考:http://bbs.wankuma.com/index.cgi?mode=al2&namber=37050&KLOG=64
そもそもClassは参照型なので、参照渡しする理由がありません。どうしてこうなった。

対策

一旦object型の変数に代入する事で回避しました。

// 引数に渡すオブジェクト
var option1 = new Option1();
object objOption1 = option1; 
int errCode = api_doSomthing(ref objOption1); //OK