0
  1. Say I have an interface IFoo with a method FooMethod() and a class Foo : IFoo.
  2. Say I have another interface IBar with method BarMethod() and a class Bar : IBar.
  3. Now I can create an object Foo obj1 = Foo() and call obj1.FooMethod().
  4. I can also create an object Bar obj2 = Bar() and call obj2.Bar().
  • I can now make a method that accepts e.g. an object of IFoo, e.g. obj1, such that
void FooExample(IFoo fooObj) 
  => fooObj.FooMethod();

FooExample(obj1);  // Because typeof(obj1) == Foo and Foo : IFoo
  • Can I somehow now make a method:
void CombinedExample((IFoo, IBar)foobarObj)
{
  foobarObj.Foo();
  foobarObj.Bar();
}

I know I can make a new (empty) interface IFooBar: IFoo, IBar such that I can now change the type of the parameter of CominedExample can be changed to IFooBar foobarObj, but I am particularly curious if there is a way of combining two (or even more) interfaces / classes to create a temporary object that inherits from these types without having to create a new empty type that just exists to combine those other types which I might only need in very few occasions.

Any suggestion to solve this 'problem' are welcome!

Leander
  • 854
  • 4
  • 17
  • *1. Say I have an interface IFoo with a method Foo() then I am able to create an object IFoo obj such that I can do: obj.Foo();* **No.** In C#, you can only create object instances from *classes*, not from interfaces. – Heinzi Jul 14 '22 at 17:02
  • It sounds like you want to create a **variable** that can only hold objects implementing both `IFoo` and `IBar`. In C#, that is (only) possible with generics: https://stackoverflow.com/q/2755948/87698. – Heinzi Jul 14 '22 at 17:04
  • 1
    class FooBar : IFoo, IBar { ... } – Hans Passant Jul 14 '22 at 17:10
  • @Heinzi, the problem with Sith-like statements like "In C#, you can only create object instances from classes, not from interfaces" (ie, absolute statements) is that they're generally wrong for a small subset of cases. For example, it is perfectly legal *in a small subset of cases* to call `new` on an interface and get back an object in C#. – Blindy Jul 14 '22 at 17:12
  • @Heinzi I rephrased my question, should be correct and more clear now – Leander Jul 14 '22 at 17:15
  • Any question that has "temporary type" in it will get the same response: gibberish. Also the part that says "I know I can make a new (empty) interface IFooBar: IFoo, IBar [...] the parameter of CominedExample can be changed to IFooBar foobarObj" -- no it can't, try it. You'll never be able to make this work. – Blindy Jul 14 '22 at 17:20
  • @HansPassant I know I can do something like that, but I want to know if I can create a type specification that can combine two different types without having to define that combination elsewhere as a separate class / interface – Leander Jul 14 '22 at 17:21
  • The closest you can get is `object` (or a generic parameter) and testing for the interfaces with `is`. – Blindy Jul 14 '22 at 17:21
  • @Blindy If I create a new interface `IFooBar : IFoo, IBar` and have a class `FooBar : IFooBar` and create an instance of that class I can pass it to a method `void Example(IFooBar foobarObj)`. But say I have a class `FooBar2 : IFoo, IBar` I am not able to pass an instance of this class to the same method. Not without this extra interface definition `IFooBar : IFoo, IBar`. – Leander Jul 14 '22 at 17:26
  • The extra interface won't help you unless you actually implement it. In other words, `FooBar2 : IFoo, IBar` will not implement `IFooBar`, even though it implements both `IFoo` and `IBar`. – Blindy Jul 14 '22 at 17:31
  • @Blindy And that was exactly the point of my question, but I seems a graceful answer has been posted. Thanks for you time anyways! – Leander Jul 14 '22 at 17:32
  • 1
    @Blindy: I honestly did not know that. Can you give me an example of *new ISomeInterface* working in C#? I thought that was only possible in Java... – Heinzi Jul 14 '22 at 17:40
  • Same here, can you explain how that works @Blindy? I can think of no situation where you can new up an interface – DavidG Jul 14 '22 at 20:24
  • Sure, COM interfaces. The actual object is built from the interface's GUID attribute! – Blindy Jul 14 '22 at 21:59

3 Answers3

1

You can leverage generics with constraints to achieve what you need. You can create a method like this:

public void DoFooBar<T>(T fooBar)
    where T : IFoo, IBar
{
    fooBar.CallFooMethod();
    fooBar.CallBarMethod();
}
DavidG
  • 113,891
  • 12
  • 217
  • 223
-1

then I am able to create an object IFoo obj [...]

You can create a variable with the interface as its type, sure, but that's not an object. It's an empty variable sitting there with literally null in it.

[...] such that I can do: obj.Foo();

You can write that, but it will crash at run time with a null reference exception. See above.

to create a temporary object that inherits

I particularly want to highlight that quote because it's so utterly ridiculous that it should be the starting point to fixing whatever's broken in your understanding.

Anyway, yes, you can have classes inherit multiple interfaces and then create instances (objects as you call them) of those classes and call the interface methods as you wish. But that's (probably?) what you meant. What you wrote is utter gibberish.

Blindy
  • 65,249
  • 10
  • 91
  • 131
-2

As far as I know, one of the main advantages of interfaces is that you can implement more that one interface in a class. Here is an example from codeguru:

 4:  using System;
 5:
 6:  public interface IShape
 7: {
 8:     // Cut out other methods to simplify example.
 9:     double Area();
10:     int Sides { get; }
11:  }
12:
13:  public interface IShapeDisplay
14:  {
15:     void Display();
16:  }
17:
18:  public class Square : IShape, IShapeDisplay
19:  {
20:     private int InSides;
21:     public  int SideLength;
22:
23:     public int Sides
24:     {
25:        get { return InSides; }
26:     }
27:
28:     public double Area()
29:     {
30:        return ((double) (SideLength * SideLength));
31:     }
32:
33:     public double Circumference()
34:     {
35:        return ((double) (Sides * SideLength));
36:     }
37:
38:     public Square()
39:     {
40:        InSides = 4;
41:     }
42:
43:     public void Display()
44:     {
45:        Console.WriteLine("nDisplaying Square information:");
46:        Console.WriteLine("Side length: {0}", this.SideLength);
47:        Console.WriteLine("Sides: {0}", this.Sides);
48:        Console.WriteLine("Area: {0}", this.Area());
49:     }
50:  }
51:
52:  public class Multi
53:  {
54:     public static void Main()
55:     {
56:        Square mySquare = new Square();
57:        mySquare.SideLength = 7;
58:
59:        mySquare.Display();
60:     }
61:  }
Dmyto Holota
  • 356
  • 1
  • 4
  • 14