Translating Objective-C adopts-protocol idioms to C#

Sometimes when looking at Objective-C samples, you might run into code that adopts protocols and you wonder how to port that code to C#. It typically looks like this:

@interface TransparentOverlay : UIView <UITableViewDelegate, UITableViewDataSource>
{
}

The above means that the "TransparentOverlay" object subclasses UIView and adopts two protocols: UITableViewDataSource and UITableViewDelegate.

The above does not really work with MonoMac or MonoTouch, since we mapped protocols into classes. In both bindings UITableViewDelegate and UITableViewDataSource are "model" classes.

The real meat of this is that somewhere in the implementation of TransparentOverlay, a UITableView will be created, and both its delegate and its data source will be configured to point to the TransparentOverlay source, something like this:

- (void) setup
{
	myTableView = [[UITableView alloc] initWithFrame:...];
	myTableView.delegate = self;
	myTableView.dataSource = self;
}

The adopted protocol allows you to perform the assignemnt there.

The equivalent code in C# needs to create a helper class that derives from the model. This is the full implementation:

class TransparentOverlay : UIView {
    UITableView tableview;

    class MySources : UITableViewSource {
        TrasparentOverlay container;

        public MySources (TrasparentOverlay container)
        {
            this.container = container;
        }

	override void MethodOne ()
	{
            container.DoSomething ();
	}
    }

    void Setup ()
    {
        tableview = new UITableView (....);

        var mySource = new MySources (this);
        tableView.Delegate = mySource;
        tableView.DataSource = mySource;
    }
}

Note that the UITableViewSource is an aggregated version of UITableViewDataSource and UITableViewDelegate, it is just a convenience Model for a very common idiom.

As you can see, instead of using "self" to point to the "TransparentOverlay" instance, you need to make it point to the mySource instance.

The methods in MySource can get access to the content of their container by using the "container" property as illustrated by the MethodOne method.

Posted on 27 Nov 2012 by Miguel de Icaza
This is a personal web page. Things said here do not represent the position of my employer.