1
votes

I'm trying to implement a monotouch binding for FastPDFKit. I'm having trouble with an inherited constructor. I'm trying to bind "ReaderViewController" from fastPDFKit. ReaderViewController inherits from MFDocumentViewController which inherits from UIViewController.

My C#

NSUrl fullURL = new NSUrl (fullPath);
FastPDFKitBinding.MFDocumentManager DocManager = new FastPDFKitBinding.MFDocumentManager (fullURL);

DocManager.EmptyCache ();


//line where the errors occur
FastPDFKitBinding.ReaderViewController pdfView = new FastPDFKitBinding.ReaderViewController (DocManager); 
pdfView.DocumentID = PageID.ToString ();

Source.PView.PresentViewController(pdfView, true, null);

This code does not build, giving me two errors when I make the new ReaderViewController:

Error CS1502: The best overloaded method match for `FastPDFKitBinding.ReaderViewController.ReaderViewController(MonoTouch.Foundation.NSCoder)' has some invalid arguments (CS1502) (iOSFlightOpsMobile)

Error CS1503: Argument `#1' cannot convert `FastPDFKitBinding.MFDocumentManager' expression to type `MonoTouch.Foundation.NSCoder' (CS1503) (iOSFlightOpsMobile)

The relevant part of my binding

namespace FastPDFKitBinding
{
    [BaseType (typeof (UIAlertViewDelegate))]
    interface MFDocumentManager {

        [Export ("initWithFileUrl:")]
        IntPtr Constructor (NSUrl URL);

        [Export ("emptyCache")]
        void EmptyCache ();

        [Export ("release")]
        void Release ();
    }

    [BaseType (typeof (UIViewController))]
    interface MFDocumentViewController {
        [Export ("initWithDocumentManager:")]
        IntPtr Constructor (MFDocumentManager docManager);

        [Export ("documentId")]
        string DocumentID { get; set; }

        [Export ("documentDelegate")]
        NSObject DocumentDelegate { set; }
    }

    [BaseType (typeof (MFDocumentViewController))]
    interface ReaderViewController {

    }
}

Now, I can get rid of the errors by taking the binding Exports from MFDocumentViewController and putting them in my ReaderViewController Interface.

    [BaseType (typeof (UIViewController))]
interface MFDocumentViewController {

}

[BaseType (typeof (MFDocumentViewController))]
interface ReaderViewController {
    [Export ("initWithDocumentManager:")]
    IntPtr Constructor (MFDocumentManager docManager);

    [Export ("documentId")]
    string DocumentID { get; set; }

    [Export ("documentDelegate")]
    NSObject DocumentDelegate { set; }
}

But I don't want to do this, because those constructors/methods are defined in MFDocumentViewController. How can I get the binding to correctly use those inherited methods/constructors.

1

1 Answers

3
votes

Your fix is the correct implementation.

Ctor inheritance in .NET (and probably all OO languages) require the base ctor to be defined. Let me give an example.

This works fine

class A {
    public A (string m) {}
}

class B : A{
    public B (string m) : base (m) {}
}

class C : B {
    public C (string m) : base (m) {}
}

When you do new C("hello"), the ctor for A, then B, then C is executed with the parameter.

This does not work:

class A {
    public A (string m) {}
}

class B : A {
    public B () : base ("empty") {}
}

class C : B {
    public C (string m) : base (m) {}
}

The reason is the compiler does have to call the B ctor (as C inherit from it) but doesn't know which ctor to use.

So, when binding an obj-C library for monotouch, make sure you re-declare all the constructors that might need to be called at some point.