Ref引数を取る静的メソッドのデリゲートを作成しようとしています。なんでこんなコカマミなことをしているのか聞かないでください。これはすべて、.Net、C#、およびリフレクションがどのように機能し、それを最適化するかを学ぶことの一部です。
私のコードは:
public struct DataRow
{
private double t;
static public void Cram_T(ref DataRow dr, double a_t)
{
dr.t = a_t;
}
}
''''
Type myType = typeof(DataRow);
MethodInfo my_Cram_T_Method = myType.GetMethod("Cram_T");
var myCram_T_Delegate =
Delegate.CreateDelegate(typeof(Action<DataRow, Double>),
my_Cram_T_Method)
as Action<DataRow, Double>;
(私が思うに)一般的なアクションがメソッドと一致しないため、これによりバインディングエラーが発生します。
ウォッチウィンドウでCram_T_Methodの値を調べると、
{Void Cram_T(DataRow ByRef, Double)}
次に、アクションでrefキーワードを使用してみました。
var myCram_T_Delegate =
Delegate.CreateDelegate(typeof(Action<ref DataRow, Double>),
my_Cram_T_Method)
as Action<ref DataRow, Double>;
しかし、これはコンパイルされません。 C#コンパイラは、トークン「ref」でチョークします。
このデリゲートを作成する正しい方法は何ですか?
独自のデリゲートタイプを作成します。
delegate void MyAction(ref DataRow dataRow, double doubleValue);
そして、Action<ref DataRow, Double>
の代わりにMyAction
を使用します。これは、ご指摘のとおり、コンパイルされません。
@Ben Mは正しい考えを持っていますが、もっと一般的にすることもできます。
public delegate void RefAction<T1, T2>(ref T1 arg1, T2 arg2)
この問題は、デリゲート自体とは何の関係もありません。型引数を指定するときにref
を使用できないだけです。
理論的には、「参照によるかどうか」は型情報の一部です(したがって、Type.IsByRef
)が、そのように指定することはできません。
率直に言って、リフレクションを介してList<ref int>
を作成しようとするとどうなるかはまったくわかりません。たとえば、-私は希望例外がスローされることを望んでいます...それは非常に賢明な概念:)
編集:私はそれを試しました:
Type refInt = typeof(int).MakeByRefType();
Type refIntList = typeof(List<>).MakeGenericType(refInt);
エラーをスローします:
Unhandled Exception: System.ArgumentException: The type 'System.Int32&' may
not be used as a type argument.