Xamarin:绑定 ios 协议/委托无法访问 structs.cs 中定义的枚举

Posted

技术标签:

【中文标题】Xamarin:绑定 ios 协议/委托无法访问 structs.cs 中定义的枚举【英文标题】:Xamarin: Binding ios protocol/delegate can't access enum defined in structs.cs 【发布时间】:2017-10-13 11:41:03 【问题描述】:

我目前正在为 EDQueue library. 创建 ios 绑定

Structs.cs 文件如下所示:

using System;
using ObjCRuntime;

namespace EDQueue



    // => Enums attributed with[NativeAttribute] must have an underlying type of `long` or `ulong`
    [Native]
    public enum EDQueueResult : long
    
        Success = 0,
        Fail,
        Critical
    


ApiDefinition.cs 文件类似于:

using System;
using Foundation;
using ObjCRuntime;

namespace EDQueue

    // typedef void (^EDQueueCompletionBlock)(EDQueueResult);
    delegate void EDQueueCompletionBlock(EDQueueResult result);

    // ETC....

    // @protocol EDQueueDelegate <NSObject>
    [Protocol, Model]
    [BaseType(typeof(NSObject))]
    interface EDQueueDelegate
    
        // @optional -(EDQueueResult)queue:(EDQueue *)queue processJob:(NSDictionary *)job;
        [Export("queue:processJob:")]
        EDQueueResult Queue(EDQueue queue, NSDictionary job);

        //// @optional -(void)queue:(EDQueue *)queue processJob:(NSDictionary *)job completion:(EDQueueCompletionBlock)block;
        //[Export("queue:processJob:completion:")]
        //void Queue(EDQueue queue, NSDictionary job, EDQueueCompletionBlock completeBlock);

    

    // ETC...

正如所写,产生以下错误: 错误 CS0426:类型名称 'EDQueueResult' 不存在于文件 EDQueueDelegate.g.cs 中的类型 'EDQueue' (CS0426) (EDQueue)

抛出错误时该文件如下所示:

//
// Auto-generated from generator.cs, do not edit
//
// We keep references to objects, so warning 414 is expected

#pragma warning disable 414

using System;
using System.Drawing;
using System.Diagnostics;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using UIKit;
using GLKit;
using Metal;
using MapKit;
using ModelIO;
using SceneKit;
using Security;
using AudioUnit;
using CoreVideo;
using CoreMedia;
using QuickLook;
using Foundation;
using CoreMotion;
using ObjCRuntime;
using AddressBook;
using CoreGraphics;
using CoreLocation;
using AVFoundation;
using NewsstandKit;
using CoreAnimation;
using CoreFoundation;

namespace EDQueue 
    [Protocol (Name = "EDQueueDelegate", WrapperType = typeof (EDQueueDelegateWrapper))]
    [ProtocolMember (IsRequired = false, IsProperty = false, IsStatic = false, Name = "Queue", Selector = "queue:processJob:", ReturnType = typeof (EDQueue.EDQueueResult), ParameterType = new Type []  typeof (global::EDQueue.EDQueue), typeof (NSDictionary) , ParameterByRef = new bool []  false, false )]
    public interface IEDQueueDelegate : INativeObject, IDisposable
    
    
// ETC...

但是,如果我删除或注释掉 [Protocol, Model] 位,则库构建不会出错。

如果我使用 EDQueueCompletionBlock 取消注释第二个函数,我也会收到类似的错误,这最终依赖于 EDQueueResult 枚举。

Structs.cs 文件的构建操作设置为 ObjcBindingCoreSource

非常感谢任何帮助。谢谢!

【问题讨论】:

难道你没有任何机会还有一个名为 EDQueue 的 type(除了具有这样名称的命名空间)吗? @Evk,感谢您的回复。有一个名为 EDQueue 的类跟踪单例/共享实例和其他一些东西。在绑定中,这是一个名为 EDQueue 的接口,带有 [BaseType(typeof(NSObject))] 这就是原因 - 它认为 EDQueue.EDQueueResult 是该 EDQueue 的内部类(不将 EDQueue 视为命名空间)。尝试只使用 EDQueueResult 或类似 global::EDQueue.EDQueueResult 的东西。 @Evk,更容易直接显示。你能看看这个并确认吗?谢谢! github.com/Sitata/edqueue-xamarin/blob/master/EDQueue/… 不知道应该看什么。正如您所说-您的接口与您的命名空间同名-这会导致诸如 EDQueue.EDQueueResult 之类的语句出现问题-该类型是 EDQueue 命名空间还是 EDQueue 类型的子类?编译器选择后者。 【参考方案1】:

由于您同时拥有命名空间 EDQueue 和名为 EDQueue 的类型(接口) - 您不能使用 EDQueue.TypeName 引用命名空间 EDQueue 中的任何类型,因此此语句:

ReturnType = typeof (EDQueue.EDQueueResult)

不会编译,因为编译器会在 EDQueue 接口内搜索成员(即使接口不能有子类,也不能有静态成员),而不是在 EDQueue 命名空间内。

解决此问题的最明显方法是永远不要有相同名称的命名空间和类型,因此重命名命名空间或类型名称。

如果这是不可能的,或者您不能完全确定它不会产生副作用 - 更改参考

ReturnType = typeof (EDQueueResult)

并将using EDQueue 添加到 usings 块中。或者,像这样引用:

ReturnType = typeof (global::EDQueue.EDQueueResult)

【讨论】:

以上是关于Xamarin:绑定 ios 协议/委托无法访问 structs.cs 中定义的枚举的主要内容,如果未能解决你的问题,请参考以下文章

使用委托绑定方法

Xamarin 表单绑定 - 访问父属性

Xamarin - 无法通过 Android(和 iOS)访问本地 api

在 iOS Xamarin Native 中设置 FSCalendarAppearance 委托

iOS - 无法访问 UITableViewCell 类中的 UITextView 委托

委托和协议无法正常工作