代表行动< ref T1,T2>

时间:2010-01-08 19:54:38

标签: c# reflection delegates

我正在尝试创建一个带有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)}

然后我尝试在Action中使用ref关键字:

  var myCram_T_Delegate = 
         Delegate.CreateDelegate(typeof(Action<ref DataRow, Double>),         
                                 my_Cram_T_Method) 
                                 as Action<ref DataRow, Double>;

但这不会编译。 C#编译器在令牌“ref”处窒息。

创建此委托的正确方法是什么?

2 个答案:

答案 0 :(得分:38)

创建您自己的委托类型:

delegate void MyAction(ref DataRow dataRow, double doubleValue);

并使用MyAction代替Action<ref DataRow, Double> - 正如您所指出的那样,它不会编译。

答案 1 :(得分:23)

@Ben M有正确的想法,虽然你可以使它更通用:

public delegate void RefAction<T1, T2>(ref T1 arg1, T2 arg2)

问题与代理无关 - 只是在指定类型参数时不能使用ref

理论上,“它是否由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.