Click here to Skip to main content
15,893,381 members
Home / Discussions / C#
   

C#

 
GeneralRe: Learning C# through exercises Pin
dybs13-Apr-12 11:20
dybs13-Apr-12 11:20 
GeneralRe: Learning C# through exercises Pin
VJ Reddy13-Apr-12 13:50
VJ Reddy13-Apr-12 13:50 
QuestionRe: Learning C# through exercises Pin
Anurag Sarkar14-Apr-12 19:52
Anurag Sarkar14-Apr-12 19:52 
AnswerRe: Learning C# through exercises Pin
VJ Reddy14-Apr-12 19:54
VJ Reddy14-Apr-12 19:54 
AnswerRe: Learning C# through exercises Pin
Richard MacCutchan12-Apr-12 21:22
mveRichard MacCutchan12-Apr-12 21:22 
AnswerRe: Learning C# through exercises Pin
V.12-Apr-12 21:47
professionalV.12-Apr-12 21:47 
AnswerRe: Learning C# through exercises Pin
BobJanova12-Apr-12 23:42
BobJanova12-Apr-12 23:42 
GeneralRe: Learning C# through exercises Pin
jeramyRR13-Apr-12 6:05
jeramyRR13-Apr-12 6:05 
AnswerRe: Learning C# through exercises Pin
Tim Groven13-Apr-12 10:54
Tim Groven13-Apr-12 10:54 
AnswerRe: Learning C# through exercises Pin
cjb11015-Apr-12 23:01
cjb11015-Apr-12 23:01 
QuestionGroup in listview C# Pin
nhanlaptrinh12-Apr-12 8:29
nhanlaptrinh12-Apr-12 8:29 
AnswerRe: Group in listview C# Pin
Mycroft Holmes12-Apr-12 12:42
professionalMycroft Holmes12-Apr-12 12:42 
GeneralRe: Group in listview C# Pin
nhanlaptrinh14-Apr-12 9:03
nhanlaptrinh14-Apr-12 9:03 
QuestionExtract ConnectionString from App.Config Pin
Jassim Rahma12-Apr-12 8:00
Jassim Rahma12-Apr-12 8:00 
AnswerRe: Extract ConnectionString from App.Config Pin
PIEBALDconsult12-Apr-12 8:08
mvePIEBALDconsult12-Apr-12 8:08 
AnswerRe: Extract ConnectionString from App.Config Pin
ZurdoDev12-Apr-12 8:56
professionalZurdoDev12-Apr-12 8:56 
GeneralRe: Extract ConnectionString from App.Config Pin
PIEBALDconsult12-Apr-12 12:08
mvePIEBALDconsult12-Apr-12 12:08 
AnswerRe: Extract ConnectionString from App.Config Pin
Bernhard Hiller12-Apr-12 21:06
Bernhard Hiller12-Apr-12 21:06 
QuestionMultiple Inhertance solution Pin
zeeShan anSari12-Apr-12 3:54
zeeShan anSari12-Apr-12 3:54 
AnswerRe: Multiple Inhertance solution Pin
zeeShan anSari12-Apr-12 4:06
zeeShan anSari12-Apr-12 4:06 
GeneralRe: Multiple Inhertance solution Pin
PIEBALDconsult12-Apr-12 4:50
mvePIEBALDconsult12-Apr-12 4:50 
GeneralRe: Multiple Inhertance solution Pin
BobJanova12-Apr-12 5:01
BobJanova12-Apr-12 5:01 
GeneralRe: Multiple Inhertance solution Pin
BobJanova12-Apr-12 23:31
BobJanova12-Apr-12 23:31 
I thought about this some more and you can make the fakery even better, as long as you can actually inherit from A and B (which is a requirement for multiple inheritance when it's supported, obviously):



class Multi { // : A, B
 private A a;
 private B b;
 
 Multi(string argForA, int argForB){
  a = new HostedA(this, argForA);
  b = new HostedB(this, argForB);
 }
 
 public static implicit operator A(Multi m) { return m.a; }
 public static implicit operator B(Multi m) { return m.b; }

 public static implicit operator Multi(A a) { return ((HostedA)a).host; }
 public static implicit operator Multi(B b) { return ((HostedB)b).host; } 

 private class HostedA : A {
  internal Multi host;
  internal HostedA(Multi host, string argsForA) : base(argsForA) {
   this.host = host;
  }
 }

 private class HostedB : B {
  internal Multi host;
  internal HostedB(Multi host, int argsForB) : base(argsForB) {
   this.host = host;
  }
 }
}


Those cast-back operators will fail if you give it the wrong sort of A or B (i.e. one that isn't a cast-out of a Multi), but that's correct (though the exception message might not be quite right). You can override behaviour 'inherited' from A and B in HostedA and HostedB, and as inner classes they have access to their host's private state and methods.

If you want Multi itself to be virtual and inheritable, you can virtualise the creation of the instances of A and B and make the hosted classes visible for inheritance:

class Multi { // : A, B
 private A a;
 private B b;
 
 Multi(string argForA, int argForB){
  a = ConstructA();
  b = ConstructB();
 }

 protected virtual HostedA ConstructA(string argForA) { return new HostedA(this, argForA); }
 protected virtual HostedB ConstructB(int argForB) { return new HostedB(this, argForB); }
 
 public static implicit operator A(Multi m) { return m.a; }
 public static implicit operator B(Multi m) { return m.b; }

 public static implicit operator Multi(A a) { return ((HostedA)a).Host; }
 public static implicit operator Multi(B b) { return ((HostedB)b).Host; } 

 protected class HostedA : A {
  public Multi Host { get; private set; }
  public HostedA(Multi host, string argsForA) : base(argsForA) {
   this.Host = host;
  }
 }

 protected class HostedB : B {
  public Multi Host { get; private set; }
  public HostedB(Multi host, int argsForB) : base(argsForB) {
   this.Host = host;
  }
 }
}


To override some of Multi's 'A' behaviour, create a new inner subclass and override the construction method:

class Subclass : Multi {
 protected override Multi.HostedA ConstructA(string argForA) { return new HostedA(argForA); }

 protected class HostedA : Multi.HostedA {
  public HostedA(Multi host, string argsForA) : base(host, argsForA) {}

  public override string ToString() { "subclassed A"; }
 }
}


... and now ((A)new Subclass("A", 12)).ToString() -> "subclassed A". Casting back with subclassing is a bit ugly though, you can't do (Subclass)(A)mySubclass, instead having to do (Subclass)(Multi)(A)mySubclass.

This retains the disadvantage over real multiple inheritance that a cast from Multi to A gives you a different object (unlike a cast from Button to Control or from an object to an implemented interface). However, the A which is returned maintains a reference to the Multi and protects it from garbage collection, and it should now be castable back (i.e. (Multi)(A)myMulti == (Multi)(B)myMulti == myMulti). And, of course, to use any A methods on a Multi instance you must do ((A)myMulti).MethodOnA(), because the compiler won't know to cast and the methods aren't actually defined on Multi (and although you could create forwarding shims, that makes your code ugly).

However, an approach where you inherit normally from one class and fake-inherit like this from another:

class Multi : A { // : A, B
 private B b;
 
 Multi(string argForA, int argForB) : base(argForA) {
  b = ConstructB();
 }
 
 protected virtual HostedB ConstructB(int argForB) { return new HostedB(this, argForB); }
 
 public static implicit operator B(Multi m) { return m.b; }
 
 public static implicit operator Multi(B b) { return ((HostedB)b).Host; } 
 
 protected class HostedB : B {
  public Multi Host { get; private set; }
  public HostedB(Multi host, int argsForB) : base(argsForB) {
   this.Host = host;
  }
 }
}


... could make sense if B is a decorator class and A is the main functionality which you want to be able to use normally.
AnswerRe: Multiple Inhertance solution Pin
RobCroll12-Apr-12 14:40
RobCroll12-Apr-12 14:40 
QuestionSetting users access permissions on tabs in C# tabcontrol Pin
Xonel11-Apr-12 22:46
Xonel11-Apr-12 22:46 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.