1

excuse me I havent dealt much with generic in c#

according to this question ,how is it possible to make a generc collection that implement two interfaces i was looking for a direct way like this:of course it makes error and totally is wrong.

interface IEmployee {void DisplayInfo();}

interface ISalary {void CalculateSalary();}


class Nurse : IEmployee, ISalary
{
 //some Implementation
}


class Doctor : IEmployee, ISalary
{
 //some Implementation
}

class EntryPoint
{
 static void Main(string[] args)
  { 
  System.Collections.Generic .List<T>  employees where T: ISalary,IEmployee
   =new System.Collections.Generic .List<T>();
  }

 Nurse oNurse = new Nurse();
 Doctor oDoctor = new Doctor();

 employees.Add(oNurse);
 employees.Add(oDoctor);
}

after some Reading i found that maybe i must define a generic class like this at first:

public class HospitalEmployee<T> where T : IEmployee, ISalary

{

}

and unfortunately it dosnt work ,Now I am confused and dont know what must to do exactly,please help,thank u

Community
  • 1
  • 1
siamak
  • 669
  • 1
  • 10
  • 28

3 Answers3

14

You can do it like this:

interface IEmployee { void DisplayInfo(); }
interface ISalaried { void CalculateSalary(); }
interface ISalariedEmployee : IEmployee, ISalaried {}
class Doctor : ISalariedEmployee { whatever }
class Nurse : ISalariedEmployee { whatever }
...
var list = new List<ISalariedEmployee>() { new Nurse(), new Doctor() };

Does that help?

Essentially the feature you really want does not exist. There is a way to say "this generic type parameter must be constructed with a type argument that implements these two interfaces" but there is, oddly enough, not a way to say "this local variable must be initialized with a reference to an object that implements these two interfaces". It is simply a shortcoming of the C# type system that you can represent that in type parameters but not in locals. What you want is:

var list = new List<IEmployee + ISalary>();

And now you can only put things into the list that implement both interfaces. But there is no such feature in C#, unfortunately. Sorry!

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • hi Mr lipprt,its great To see you On this post,your solution Saved me ,Thank u ,but just for curiosity,I am wondering is it Possible to handle this without using Combinded Interface? – siamak Jan 31 '11 at 19:33
  • thank you again for Update,It would be great If C# Team could Cover this .OF Course I am Not An Idealist.-) – siamak Jan 31 '11 at 20:01
  • A more useful general purpose solution would be type pattern matching or type classes :) – James Dunne Feb 01 '11 at 01:21
  • @James Dunne:its very intersting and attractive to see a general solution ,could you pleas give some code for your suggestion,it would be so useful,thank u very much – siamak Feb 01 '11 at 13:02
  • 2
    @siamak: James is making a bit of a joke. Those features are not supported by C#. Functional languages like F# or Haskell have those features in their type systems. – Eric Lippert Feb 01 '11 at 15:06
  • I didn't mean to erroneously imply that was already a feature of C#, but was just putting it out there as a more general wish-list feature since you mentioned the wished-for "A + B" feature. :) – James Dunne Feb 01 '11 at 16:28
  • @Eric:at the first glance ,i thought its possible to have a general solution(a general solution is Rock and roll-:) but now maybe james was right.i think something like that would help to flexibility of language,do u think it could be a good and possible suggestion for moicrosoft or its better we dont follw up? thank u again – siamak Feb 01 '11 at 18:48
  • @siamak: We often bring ideas inspired by functional languages into OO languages; that's why we've added lambda expressions, type inference and query comprehensions to C# and VB. I think that features like pattern matching or "higher" types are fascinating features worth learning about, but it is not clear that there is an path that gets them into OO languages like C# and VB. I would not expect that kind of extension to the type system any time soon. – Eric Lippert Feb 01 '11 at 19:14
1

It is not clear what are you trying to do: create your own generic container or use List<T> to store different objects.

But as far as I understood you need something like this:

List<IEmployee> employees = new List<IEmployee>();
Nurse oNurse = new Nurse();
Doctor oDoctor = new Doctor();

employees.Add(oNurse);
employees.Add(oDoctor);

UPDATE

Just create an interface which inherits all interfaces want to use like:

interface IEmployeeWithSalery: IEmployee, ISalery {}
List<IEmployeeWithSalery> employees = new List<IEmployeeWithSalery>()
Elalfer
  • 5,312
  • 20
  • 25
  • I just want to have a List of objects that implemet two interfaces (ISalary and Iemployee),it seems your solution is suitable for one interface – siamak Jan 31 '11 at 18:23
  • Re: your update: And what makes Doctor magically implement IEmployeeWithSalary if it does not already? The point of the question is that the effective interface set of a generic type parameter enables you to expression the intersection of types that implement two interfaces *without* resorting to a third interface derived from both. But there is no way to express that in the type system outside of the effective interface set of a generic type parameter. – Eric Lippert Feb 01 '11 at 19:17
0

This sounds a lot like my question Storing an object that implements multiple interfaces and derives from a certain base (.net) which I asked a few weeks ago. I offer a possible workaround there which may be more work than defining and using a few "combined" interface types, but has the advantage that one can define an object to work with any particular combination of interfaces which are suitably defined without having to define a new "combined" interface type for that combination.

Community
  • 1
  • 1
supercat
  • 77,689
  • 9
  • 166
  • 211