RSS 2.0 Feed
2005-08 Entries
摘要:研究Int32&的时候,无意中发现C#里面还有4个Undocument Keyword, 分别是__makeref, __reftype, __refvalue 以及__arglist。 其中前三个keyword可以这样用:         int i = 1;                  TypedReference tr = __makeref(i);         Type t = __reftype(tr); //t = System.Int32                  int i1 = __refvalue(tr, int); //i1 = 1         int i2 = (int)TypedReference.ToObject(tr); //i2 = 1                  i++; //i = 2                  int i3 = __refvalue(tr, int); //i3 = 2 (关于TypedReference类型MSDN是这样描述的:Describes objects that contain both a managed pointer to a location and a runtime representation of the type that may be stored at that location. 同时TypedReference有 [CLSCompliant(false)]标记) 于是我们可以用下面这种方法来模拟ByRef的参数 public class MyClass {     public static void Main()     {         int v = 99;         TypedReference trParameters = __makeref(v);         Foo(trParameters);         Console.WriteLine("v = {0}", v); // v = 100      }          public static void Foo(TypedReference tr)     {         if(__reftype(tr) == typeof(int))         {             __refvalue(tr, int)++;         }     } } 比较不爽的就是我们必须在Foo方法体中判断TypedReference包含的类型。 注意如果把Foo写成public static void Foo(ref TypedReference tr),编译器会抱怨说:Method or delegate parameter cannot be of type 'ref System.TypedReference'。 至于__arglist则可以模拟params关键字,抄个例子: public void Function(__arglist)  {     ArgIterator iterator = new ArgIterator(__arglist);     for (int count=iterator.GetRemainingCount(); count>0; count--)     {         TypedReference typedRef = iterator.GetNextArg();         Console.WriteLine(__refvalue(typedRef, int));    } } 调用它:Function(__arglist(2,3,4));  输出2,3,4 后注:这4个keyword毕竟是undocument的,微软也没有提供任何支持,所以不排除以后被delete掉。Mono下面的编译器似乎也不支持,不过我在vs2005 beta里面试验还是有效的。  Updated: Flier Lu在他的blog对__arglist的使用作了更深入的探讨,推荐阅读。 :)...[阅读全文]

posted @ | Feedback (3) |

摘要:话说有一天你要用反射来对Target类进行操作,调用Foo函数。 public class Target ...{ public void Foo(int x, int y, int z) ...{ } public void Foo(int x, ref int y, out int z) ...{ } } 可以看到Foo有2个重载,唯一的区别在于第二个Foo方法签名中有带ref的参数。 如果你直接写: Target myTarget = new Target(); Type t = myTarget.GetType(); MethodInfo methodInfoWithRefParamters = t.GetMethod("Foo"); 那么会在RunTime扔个Exception说: Ambiguous match found. 要想invoke第二个Foo的话,我们必须这样写: MethodInfo methodInfoWithRefParamters ;Type[] typeList = new Type[] {typeof(int), Type.GetType("System.Int32&"),Type.GetType("System.Int32&") };methodInfoWithRefParamters = t.GetMethod("Foo", typeList ); 好吧,现在运行是正常运行了,可是新的问题又来了:这个System.Int32&是个啥东东呢?   先在MSDN/.Net Reflector找找Int32&,没有。Google和查看微软放出的Framework Source Code,同样无果。   得,现成的资料找不到,那只有让我们自己通过做试验来玩玩了。   1。 先试试能不能搞一个Int32&的实例出来: 当然,就不用指望直接能在C#里面new一个Int32&了。(如果是unsafe的话,Int32*到还可以) 来试试亲爱的Activator吧: Type refInt32Type = Type.GetType("System.Int32&"); object myRefInt = System.Activator.CreateInstance(refInt32Type, true); 哎呀,扔了一个“No parameterless constructor defined......[阅读全文]

posted @ | Feedback (12) |