问题是属性/方法是[Static] 和[Category]。绑定生成器尝试使用扩展方法(需要实例)或扩展类型(因为它是 UIKit 类型,所以它不能这样做)。
非 UIKit 基本类型
最简单的解决方案是强制生成器尽其所能,然后您可以提供帮助。可能有更好的方法,但这是可行的。
首先,将所有[Static] 成员移动到一个新类型中(如果它们都是静态的,则跳过这个)。使用用户友好的名称可能会很好,因为他们实际上会输入这个名称。在你的情况下,你可以使用SDAutoLayoutUIView 或其他东西。
然后,删除[Category] 属性,将[Static] 属性添加到类,并确保[BaseType] 属性存在。
这将创建一个关于 class_ptr 不存在的编译器错误。这是因为该类别期望生成器做某事,但由于某种原因它没有......(听起来像一个错误。)
无论如何,只需创建一个包含单个成员的小类作为附加文件:
private static readonly IntPtr class_ptr = Class.GetHandle("UIView");
现在,一切都应该正常了。最终代码在Additions.cs中是这样的:
partial class SDAutoLayoutUIView
{
private static readonly IntPtr class_ptr = Class.GetHandle("UIView");
}
你的绑定代码应该是这样的:
// ...
[Category]
[BaseType(typeof(UIView))]
interface UIView_SDAutoLayout
{
// ... instance methods
}
[Static]
[BaseType(typeof(UIView))]
interface SDAutoLayoutUIView
{
// ... static methods
// -(SDAutoLayoutModel *)sd_layout;
[Static]
[Export("sd_layout")]
SDAutoLayoutModel Sd_layout ();
}
// ...
应该这样做。这个选项很棒,因为我们只需要为一整套方法做一行。如果只有一两个,这实际上并没有那么大的优势,但仍然是更少的工作。
UIKit 基本类型
如果对象不是从UIView 继承的,上述方法可以正常工作。这是因为生成器为 UIKit 类做了额外的工作来获得外观位绑定。
如果是这种情况,您将不得不保留生成的绑定,但将其设为[Internal]。以下是更多信息:
https://github.com/xamarin/xamarin-macios/pull/1862
所以,你的绑定代码应该是这样的(原来是新的[Internal]):
[Category]
[BaseType(typeof(UIView))]
interface UIView_SDAutoLayout
{
// -(SDAutoLayoutModel *)sd_layout;
[Static]
[Internal]
[Export("sd_layout")]
SDAutoLayoutModel Sd_layout();
}
但是,您的添加代码会正确执行:
partial class UIView_SDAutoLayout
{
public static SDAutoLayoutModel Sd_layout()
{
// use the extension method
return (null as UIView).Sd_layout();
}
}
这很有效,因为我们向用户隐藏了奇怪的扩展方法,并将其包装成一个不需要空值的漂亮静态方法。实际上,这是工具的限制,因为它总是使用类别的扩展方法,但静态方法不能是 C# 中的扩展。
注意:您可能希望为该类使用一个好听的名称:SDAutoLayoutUIView
如果基类型是 UIKit 类型,例如 UIView,这很好。 (这也适用于任何类型,并且不限于 UIKit 类型。)但是,它确实需要将所有静态方法标记为内部方法,然后为每个方法创建正确的重载。如果你需要它们没问题,而且通常没有那么多事情要做。
拥有的基本类型
最好和最简单的情况是您拥有基本类型。例如,如果这是您的绑定:
[BaseType(typeof(UIView))]
interface MyThing
{
}
[Category]
[BaseType(typeof(MyThing))]
interface Others_MyThing
{
[Static]
[Export("createNewThing")]
MyThing CreateNewThing ();
}
在这种情况下,只需简单地将成员移动到非类别类型中:
[BaseType(typeof(UIView))]
interface MyThing
{
[Static]
[Export("createNewThing")]
MyThing CreateNewThing ();
}
[Category]
[BaseType(typeof(MyThing))]
interface Others_MyThing
{
}