12

I have a set of Class A and Class B both have Some properties. and another Class C which has their own properties.

Whenever i create a instance of class C i want to access all properties of all three classes with objClassC.

How can i Achieve this in C#?

I m facing two problem :-

  1. I can not inherit both the classes A, B in Class C (C# doesn't Support Multiple Inheritance)
  2. if i use Interface instead of Class A, B (In Interface we can not Contains Fields)
abatishchev
  • 98,240
  • 88
  • 296
  • 433
Shashank
  • 6,117
  • 20
  • 51
  • 72
  • 3
    You can use composition. There's also [mixins](http://stackoverflow.com/questions/255553/is-it-possible-to-implement-mixins-in-c) – Niklas B. May 04 '12 at 11:09

7 Answers7

29

Why don't you contain instance of Class A and Class B inside Class C. Use Composition

class C
{
//class C properties
public A objA{get;set;}
public B objeB{get;set;}
}

Then you can access

C objc = new C();
objc.objA.Property1 = "something";
objc.objB.Property1 = "something from b";

check out the article Composition vs Inheritance

EDIT:

if i use Interface instead of Class A, B (In Interface we can not Contains Fields)

Well, interfaces can't contain fields, if you define one, you will get compilation error. But interfaces can contain properties with the exception that you can't specify the access specifiers, as all elements of the interface are considered public. You can define properties for Interface 'A' and 'B' as:

public interface IA
{
     int Property1 { get; set; }
}


public interface IB
{
    int Property2 { get; set; }
}

Then you can implement them in the class C like:

public class C : IA, IB
{
    public int Property1 { get; set; }
    public int Property2 { get; set; }
}

Later you can use them as:

C objC = new C();
objC.Property1 = 0;
objC.Property1 = 0;
Habib
  • 219,104
  • 29
  • 407
  • 436
  • But if implementation of IA, IB is necessary in class C then what is need to implement IA, and IB? we can just define properties without implementing interfaces...? – Umar Abbas Apr 04 '14 at 06:06
  • @UmarAbbas, the only advantage of doing that would be holding object of class `C` or any other class implementing interface `IA` and `IB`, in IA or IB, and have the polymorphic behaviour. The above code is just for an example, I have yet to come with a real life scenario where interface just has a bunch of properties and no methods. – Habib Apr 04 '14 at 12:06
  • But Class C have Its own properties. we can also create object of class C without implementing IA, IB. so why we implemented class C with interface IA, IB ? – Umar Abbas Apr 04 '14 at 17:59
  • and how it is multiple inheritance if we hold object of imp class in IA, IB? why we say it Multiple inheritance? when we still need 'Polymorphism' and 'Composition' Thanks for Reply! :) – Umar Abbas Apr 04 '14 at 18:07
  • @UmarAbbas, There is no multiple inheritance in C# *(and as much as I remember Java)*. The above example is explaining whether interface can have properties or not, and *somewhat* trying to mimic multiple inheritance by implementing two interfaces. It is NOT pure Multiple Inheritance and there is no way in C# to do multiple inheritance – Habib Apr 04 '14 at 18:39
4

Interfaces can have properties but if you also want to use the methods the composition or dependence injection might be required.

Interface A
{
   int PropA {get; set;}
}


Interface B
{
  int PropB {get; set;}
}

class C : A, B
{

}

// put these statement in some method

C c = new C();
c.PropA = 1;
c.PropB = 2;
Adil
  • 146,340
  • 25
  • 209
  • 204
3

Interfaces are not a solution to the lack of Multiple Inheritance. They just don't do the same things. The closest you can get is make C be a subclass of A, and have a property of type B. Perhaps if you tell us what A, B and C should do, we can give an answer that better fits your needs...

Alejandro B.
  • 4,807
  • 2
  • 33
  • 61
2

Interfaces may contain properties, ie.:

public interface IFoo
{
    string Bar { get; set; }
}
empi
  • 15,755
  • 8
  • 62
  • 78
2

Consider how the properties are exposed differently to the client when using inheritance vice composition.

Inheritance:

    var myCclass = new Cclass;
    myClass.propertyA;
    myClass.propertyB;
    myClass.propertyC;
    // and so on

Composition:

 var myCclass = new Cclass;
    myCclass.bClass.propertyB;
    myCclass.aClass.propertyA;
    myCclass.propertyC;

Inheritance gives a cleaner API - a good thing.

Composition requires me to know something about the internal structure of the class - not such a good thing. This violates the law of demeter - better known as the principle of least knowledge. You can get around this by having Cclass properties that one-for-one expose/return the Bclass & Aclass properties - and your Bclass & Aclass references would then be private or protected in Cclass. AND Cclass has total control over what's exposed rather than depending on A & B to not have public stuff you don't was exposed.

I agree with @AlejoBrz, interfaces is not appropriate here.

I also give a nod to "prefer composition over inheritance." But this is a guideline, not a hard and fast rule.

radarbob
  • 4,964
  • 2
  • 23
  • 36
1
public interface IAA
{
    string NameOfA { get; set; }
}
public class AA : IAA
{
    public string NameOfA{get;set;}
}

public interface IBB
{
    string NameOfB { get; set; }
}    
public class BB : IBB
{
    public string NameOfB{get;set;}
}

public class CC : IAA, IBB
{
    private IAA a;
    private IBB b;            

    public CC()
    {
        a = new AA{ NameOfA="a"};
        b = new BB{ NameOfB="b"};
    }

    public string NameOfA{
        get{
            return this.a.NameOfA;
           }
        set{
            this.a.NameOfA = value;
           }
    }

    public string NameOfB
    {
        get{
            return this.b.NameOfB;
        }
        set{
            this.b.NameOfB = value;
        }
    }
}
daryal
  • 14,643
  • 4
  • 38
  • 54
1

Interfaces cannot contain fields, but they can contain properties. In most cases, properties can be used like fields, and there is no difficulty with saying:

interface ISomeProperties
  {int prop1 {get;set;}; string prop2 {get; set;}}
interface IMoreProperties
  {string prop3 {get;set;}; double prop4 {get; set;}}
interface ICombinedProperties : ISomeProperties, IMoreProperties; 
  { }

Given a storage location of type ICombinedProperties, one may access all four properties directly and without fuss.

It should be noted, though, that there are a few things that can be done with fields which cannot be done with properties. For example, while a field may be passed to Interlocked.Increment a property cannot; attempting to Interlocked.Increment a property by copying it to a variable, calling Interlocked.Increment on that, and then copying the result back to the property might "work" in some cases, but would fail if two threads attempted to do the same thing simultaneously (it would be possible e.g. for both threads to read a value of 5, increment it to 6, and then write back 6, whereas having two threads call Interlocked.Increment on a field that was initially equal to 5 would be guaranteed to yield 7.).

To get around this, it may be necessary to have the interface include some methods which either perform an interlocked method on a field (e.g. one could have a function which calls Interlocked.Increment on the field and returns the result) and/or include functions which will call a specified delegate with a field as a ref parameter (e.g.

delegate void ActionByRef<T1>(ref T1 p1);
delegate void ActionByRef<T1,T2>(ref T1 p1, ref T2 p2);
delegate void ActionByRef<T1,T2,T3>(ref T1 p1, ref T2 p2, ref T3 p3);
interface IThing
{ // Must allow client code to work directly with a field of type T.
  void ActOnThing(ActionByRef<T> proc);
  void ActOnThing<ExtraT1>(ActionByRef<T, ExtraT1> proc, ref ExtraT1 ExtraP1);
  void ActOnThing<ExtraT1, ExtraT2>
       (ActionByRef<T> proc, ref ExtraT1 ExtraP1, ref ExtraT2 ExtraP2);
}

Given an instance of the interface, one could do something like:

  theInstance.ActOnThing(
    (ref int param) => Threading.Interlocked.Increment(ref param)
  );

or, if one had local variables maskValue and xorValue and wanted to atomically update the field with field = (field & maskValue) ^ xorValue:

  theInstance.ActOnThing(
    (ref int Param, ref int MaskValue, ref int XorValue) => {
        int oldValue,newValue;
        do {oldValue = param; newValue = (oldValue & MaskValue) ^ XorValue;
        while (Threading.Interlocked.CompareExchange(ref Param, newValue, oldValue) !=
          oldValue),
    ref maskValue, ref xorValue);
  );

If there were only a few types of actions one would want to perform on the fields, it would be simplest to simply include them within the interface. On the other hand, the approach given above allows an interface to expose its fields in such a way as to allow clients to perform arbitrary sequences of actions upon them.

supercat
  • 77,689
  • 9
  • 166
  • 211
  • @radarbob: Part of the question had to do with the fact that interfaces cannot contain fields. Other answers acknowledged that in many cases one may use properties instead of fields. I wanted to amplify the fact that it's possible to use interfaces even when one wants to use fields in ways for which properties are not an acceptable substitute. – supercat Aug 10 '12 at 14:50