Xamarin(C#)中AbsListView.Class.GetDeclaredMethod报CS0120解决方法
报错原因
CS0120报错是因为Xamarin.Android的绑定规则中,Class是Java.Lang.Object的实例属性,无法直接通过类名静态调用。获取Java类引用不需要对应类的实例,直接调用静态方法Java.Lang.Class.FromType()即可。
除此之外你最初写的反射代码遗漏了方法参数类型声明:和Java反射逻辑一致,GetDeclaredMethod需要传入方法名+所有形参对应的Java类型,才能精准匹配到隐藏的performLongPress方法。
完整实现代码
// 获取AbsListView对应的Java类引用,无需类实例 var absListViewClass = Java.Lang.Class.FromType(typeof(AbsListView)); // 匹配目标方法签名:参数依次为View、int基本类型、long基本类型 var longPressMethod = absListViewClass.GetDeclaredMethod( "performLongPress", Java.Lang.Class.FromType(typeof(View)), Java.Lang.Integer.Type, // 匹配Java int基本类型,不要用包装类类型 Java.Lang.Long.Type // 匹配Java long基本类型,不要用包装类类型 ); // 跳过权限检查,允许访问隐藏/非公开方法 longPressMethod.Accessible = true; // 反射调用方法,参数顺序与Java代码完全对齐 // 第一个参数为方法所属的AbsListView实例,对应Java代码中invoke的第一个参数view // 后续参数依次为SwipeLayout实例、列表项位置p、视图ID vId var handled = (bool)longPressMethod.Invoke( listViewInstance, this, // 对应Java代码的SwipeLayout.this new Java.Lang.Integer(p), new Java.Lang.Long(vId) );
避坑说明
- 反射Java基本类型参数时,必须使用
Java.Lang.[对应类型].Type获取类型标识。如果用Java.Lang.Class.FromType(typeof(int))拿到的是java.lang.Integer包装类的类型,和原生方法的int基本类型签名不匹配,会抛出NoSuchMethodException。 Invoke传入的第一个参数必须是实际承载方法的AbsListView实例,和你Java代码里的调用逻辑保持一致。- 参数顺序、类型必须和原生方法签名完全对应,否则会出现参数不匹配、调用错误方法的问题。
内容的提问来源于stack exchange,提问作者Mairasheq
相关产品推荐
相关产品推荐

