Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple inheritance in C# - again

Tags:

c#

asp.net

I know that C# does not offer multiple inheritance. And I know there' are workarounds like this one for instance.

But here's a problem that I faced today, can't figure any ELEGANT workaround. I'll add some abstract code-sample so you get it quicker...

(let it be a real-life ASP.NET code - cause those "class A, class B" code-samples are really confusing):

public class AdminPage : System.Web.UI.Page
{
    protected override void OnInit(EventArgs e)
    {
        //if not an admin - get out
        if(!CurrentUserIsAdmin()) Response.End();

        base.OnInit (e);
    }
}

public class JQueryPage : System.Web.UI.Page
{
    protected override void OnInit(EventArgs e)
    {
        RegisterJQueryScript();
        base.OnLoad (e);
    }
}

//now here's what I REALLY miss in C#
public class AdminJQueryPage : AdminPage, JQueryPage;
like image 296
Alex from Jitbit Avatar asked Dec 04 '22 14:12

Alex from Jitbit


2 Answers

Compose out the functionality? This is better for Single Responsibility. You'd have to think carefully about your constructors.

interface IAdminPage {
  public string AdminPageMethod();
}

interface IJQueryPage {
  public string JQueryPageMethod();
}

internal class AdminPage : IAdminpage {
  private string someString;

  internal AdminPage(string value) {
    this.someString = value;
  }

  public string AdminPageMethod() {
    return "AdminPage result with some string: " + this.someString;
  }
}

internal JQueryPage : IJQueryPage {
  private int someNumber;

  internal JQueryPage(int value) {
    this.someNumber = value;
  }

  public string JQueryPageMethod() {
    return "JQueryPage result with number: " + this.someNumber;
  }
}

class AdminJQueryPage : IQueryPage, IAdminpage {
  private readonly IAdminPage adminPage;
  private readonly IJQueryPage jqueryPage;

  public AdminJQueryPage(string someString, int someNumber) {
    this.adminPage = new AdminPage(someString);
    this.jqueryPage = new JQueryPage(someNumber);
  }

  public string AdminPageMethod() {
    return this.adminPage.AdminPageMethod();
  }

  public string JQueryPageMethod() {
    return this.adminPage.JQueryPageMethod();
  }
}

If you really want multiple inheritance, look at Scala's traits

Edit: added passing of constructor values to composed out classes. Also made the classes internal (cannot be accessed or constructed outside the assembly) because they are only ever constructed by the AdminJQueryPage class, which is the 'public-facing' class.

like image 133
Joe Avatar answered Dec 14 '22 23:12

Joe


I came from C++ too and dont miss it, especially since reading Refactoring [and using a non-OOTB tool for that].

You can use PostSharp to post process based on placing attributes on your AdminJQueryPage which would achieve the exact same effect.

Or you can Extract Method code into helper classes and call that (i.e., Joe's example)

Or you can put the helpers in a single base class and call from that.

Either way your code will be clearer.

It's only a matter of time before your mixins start overlapping, and then your general suite of techniques for managing that complexity needs to kick in - in C++, MI should only have been one tool in a suite - rather than a very sexy hammer.

like image 27
Ruben Bartelink Avatar answered Dec 14 '22 22:12

Ruben Bartelink