A colleague and I are having a bit of an argument over multiple inheritance. I'm saying it's not supported and he's saying it is. So, I thought that I'd ask the brainy bunch on the net.
Sorry, you cannot inherit from multiple classes. You may use interfaces or a combination of one class and interface(s), where interface(s) should follow the class name in the signature.
interface A { }
interface B { }
class Base { }
class AnotherClass { }
Possible ways to inherit:
class SomeClass : A, B { } // from multiple Interface(s)
class SomeClass : Base, B { } // from one Class and Interface(s)
This is not legal:
class SomeClass : Base, AnotherClass { }
Nope, use interfaces instead! ^.^
Multiple inheritance is not supported in C#.
But if you want to "inherit" behavior from two sources why not use the combination of:
Composition
Dependency Injection
There is a basic but important OOP principle that says: "Favor composition over inheritance".
You can create a class like this:
public class MySuperClass
{
private IDependencyClass1 mDependency1;
private IDependencyClass2 mDependency2;
public MySuperClass(IDependencyClass1 dep1, IDependencyClass2 dep2)
{
mDependency1 = dep1;
mDependency2 = dep2;
}
private void MySuperMethodThatDoesSomethingComplex()
{
string s = mDependency1.GetMessage();
mDependency2.PrintMessage(s);
}
}
As you can see the dependecies (actual implementations of the interfaces) are injected via the constructor. You class does not know how each class is implemented but it knows how to use them. Hence, a loose coupling between the classes involved here but the same power of usage.
Today's trends show that inheritance is kind of "out of fashion".
C# 3.5 or below does not support the multiple inheritance, but C# 4.0 could do this by using, as I remembered, Dynamics.
You cannot do multiple inheritance in C# till 3.5. I dont know how it works out on 4.0 since I have not looked at it, but #tbischel has posted a link which I need to read.
C# allows you to do "multiple-implementations" via interfaces which is quite different to "multiple-inheritance"
So, you cannot do:
class A{}
class B{}
class C : A, B{}
But, you can do:
interface IA{}
interface IB{}
class C : IA, IB{}
HTH
C# does not support multiple inheritance of classes, but you are permitted to inherit/implement any number of interfaces.
This is illegal
(B, C, D & E are all classes)
class A : B, C, D, E
{
}
This is legal
(IB, IC, ID & IE are all interfaces)
class A : IB, IC, ID, IE
{
}
This is legal
(B is a class, IC, ID & IE are interfaces)
class A : B, IC, ID, IE
{
}
Composition over inheritance is a design pattern that seems to be favorable even in languages that support multiple inheritance.
Actually, it depends on your definition of inheritance:
you can inherit implementation (members, i.e. data and behavior) from a single class, but
you can inherit interfaces from multiple, well, interfaces.
This is not what is usually meant by the term "inheritance", but it is also not entirely unreasonable to define it this way.
Like Java (which is what C# was indirectly derived from), C# does not support multiple inhertance.
Which is to say that class data (member variables and properties) can only be inherited from a single parent base class. Class behavior (member methods), on the other hand, can be inherited from multiple parent base interfaces.
Some experts, notably Bertrand Meyer (considered by some to be one of the fathers of object-oreiented programming), think that this disqualifies C# (and Java, and all the rest) from being a "true" object-oriented language.
You may want to take your argument a step further and talk about design patterns - and you can find out why he'd want to bother trying to inherit from multiple classes in c# if he even could
Simulated Multiple Inheritance Pattern
http://www.codeproject.com/KB/architecture/smip.aspx
Multiple inheritance allows programmers to create classes that combine aspects of multiple classes and their corresponding hierarchies. For ex. the C++ allows you to inherit from more than one class
In C#, the classes are only allowed to inherit from a single parent class, which is called single inheritance. But you can use interfaces or a combination of one class and interface(s), where interface(s) should be followed by class name in the signature.
Ex:
Class FirstClass { }
Class SecondClass { }
interface X { }
interface Y { }
You can inherit like the following:
class NewClass : X, Y { }
In the above code, the class "NewClass" is created from multiple interfaces.
class NewClass : FirstClass, X { }
In the above code, the class "NewClass" is created from interface X and class "FirstClass".
In generally, you can’t do it.
Consider these interfaces and classes:
public class A { }
public class B { }
public class C { }
public interface IA { }
public interface IB { }
You can inherit multiple interfaces:
class A : B, IA, IB {
// Inherits any single base class, plus multiple interfaces.
}
But you can’t inherit multiple classes:
class A : B, C, IA, IB {
// Inherits multiple base classes, plus multiple interfaces.
}
You can't inherit multiple classes at a time. But there is an options to do that by the help of interface. See below code
interface IA
{
void PrintIA();
}
class A:IA
{
public void PrintIA()
{
Console.WriteLine("PrintA method in Base Class A");
}
}
interface IB
{
void PrintIB();
}
class B : IB
{
public void PrintIB()
{
Console.WriteLine("PrintB method in Base Class B");
}
}
public class AB: IA, IB
{
A a = new A();
B b = new B();
public void PrintIA()
{
a.PrintIA();
}
public void PrintIB()
{
b.PrintIB();
}
}
you can call them as below
AB ab = new AB();
ab.PrintIA();
ab.PrintIB();
It does not allow it, use interface to achieve it.
Why it is so?
Here is the answer: It's allowed the compiler to make a very reasoned and rational decision that was always going to consistent about what was inherited and where it was inherited from so that when you did casting and you always know exactly which implementation you were dealing with.
C# does not support multiple inheritance built in.
For adding multiple inheritance to languages that does not support it, You can use twin design pattern
As an additional suggestion to what has been suggested, another clever way to provide functionality similar to multiple inheritance is implement multiple interfaces BUT then to provide extension methods on these interfaces. This is called mixins. It's not a real solution but it sometimes handles the issues that would prompt you to want to perform multiple inheritance.
I recently somehow got to the same mindset, inheriting two classes into a class and ended up on this page (even though i know better) and would like to keep reference to the solution i found perfect in this scenario, without enforcing implementation of interfaces
My solution to this problem would be splitting up your data into classes that make sense:
public class PersonAddressSuper
{
public PersonBase Person { get; set; }
public PersonAddress Address { get; set; }
public class PersonBase
{
public int ID { get; set; }
public string Name { get; set; }
}
public class PersonAddress
{
public string StreetAddress { get; set; }
public string City { get; set; }
}
}
Later on in your code, you could use it like this:
Include Both Parts, Base & Address
PersonAddressSuper PersonSuper = new PersonAddressSuper();
PersonSuper.PersonAddress.StreetAddress = "PigBenis Road 16";
Base Only:
PersonAddressSuper.PersonBase PersonBase = new PersonAddressSuper.PersonBase();
PersonBase.Name = "Joe Shmoe";
Address Only:
PersonAddressSuper.PersonAddress PersonAddress = new PersonAddressSuper.PersonAddress();
PersonAddress.StreetAddress = "PigBenis Road 16";
Related
Intro
I am creating an ASP.NET Web API application with Entity Framework. What I need to do is return different representations of the same resource for one URI, depending on user role. For example, api/employees/1 will return two different objects for admin and standard user:
Standard user
public class EmployeeBasic
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Admin
public class EmployeeExtended : EmployeeBasic
{
public decimal Salary { get; set; }
}
The idea and the attempts
For each resource representation, I will need to provide some related classes, let's say Sort Models for example. I was wondering if it is possible to use generic types and inheritance to create a generic repository methods for related representations. I thought of the following way of doing this:
Create some base interface for Sort Models:
public interface ISortModel<out TBusinessEntity>
{
//
}
Create generic SortModel as a base type for all sort models
public abstract class SortModel<TDBEntity, TBusinessEntity> : ISortModel<TBusinessEntity>
{
// Database sorting
public abstract IQueryable<TDBEntity> ApplyToQuery(IQueryable<TDBEntity> query);
// Local sorting
public abstract IEnumerable<TBusinessEntity> ApplyToLocal(IEnumerable<TBusinessEntity> localList);
// ...
// Some private logic (expression mappers, etc.)
}
Create sort model for basic resource
public class EmployeeBasicSortModel : SortModel<DBModel.Employee, EmployeeBasic>
{
public int FullName { get; set; }
public override IQueryable<DBModel.Employee> ApplyToQuery(IQueryable<DBModel.Employee> query)
{
// implementation
}
public override IEnumerable<EmployeeBasic> ApplyToLocal(IEnumerable<EmployeeBasic> localList)
{
// implementation
}
}
Extend the basic sort model and add sorting for the extended resource properties
public class EmployeeExtendedSortModel : EmployeeBasicSortModel //, ... Is it possible to somehow do that?
{
public override IEnumerable<EmployeeExtended> ApplyToLocal(IEnumerable<EmployeeExtended> localList)
{
var partiallyOrderedList = base.ApplyToLocal(localList);
// Add extended sorting
}
// ... ?
}
Use the above classes to create generic service:
class EmployeesService()
{
public IList<TEmployee> GetAll<TEmployee>(ISortModel<TEmployee> sortModel)
where TEmployee : BasicEmployee
{
// implementation
}
}
The problem
When I thought about it for the first time, it seemed pretty simple. But when I started implementing this, I couldn't figure out the way to implement Step 4. Either I am missing something in my C# knowledge (which is quite possible) or this is not possible in the way I am trying to do this.
So the question is: can I create a base class with generic type, derive from it with basic resource as a type and derive one more time with the extended class?
Holy goodness this is a complicated question. The generics are a huge red herring. Ignore the generics; the problem is more fundamental. Let's simplify it greatly.
class Animal {}
class Mammal : Animal {}
class Tiger : Mammal {}
class Shape {}
class Square : Shape {}
class GreenSquare : Square {}
class B
{
public virtual Mammal Frob(Square s) { ... }
}
class D : B
{
public override SomeReturnType Frob(SomeArgumentType m) { ... }
}
The question is: what are legal return and argument types for this virtual override?
The answer is: in C# the only legal types are those that exactly match the overridden method's types. An override of Frob must return Mammal and take Square.
Now, we could in theory make it typesafe for D.Frob to return Tiger. Do you see why? If we have a D converted to B, then it returns a Tiger, but a Tiger is an Animal, so we're OK.
This feature is called return type covariance, and it has been suggested for C# for, oh, some 15 years now, and has never been implemented. It is not supported by the CLR, and it is not a high priority for the design team, and it creates new flavours of the Brittle Base Class Problem, and all these are such points against that it is unlikely to meet the bar any time soon.
C++ does support this feature, including on the CLR, so it is possible to do on the CLR. You just end up having to generate a bunch of helper methods.
Of course we cannot have D.Frob return Animal. It could return a Turtle, but B.Frob promises to only return Mammals.
What about the argument type? It could be typesafe to have D.Frob take Shape. Again, same reasoning: if we have a D converted to B then we will only get squares. But it would not be safe to have D.Frob take a GreenSquare, because B.Frob promises to be able to take any square, not just green squares.
This feature is called formal parameter type contravariance and few languages implement it.
Now, you want return type covariance and formal parameter type covariance, which is neither supported nor typesafe. Interestingly enough, Eiffel supports this kind of covariance.
C# developers who want return type covariance usually end up doing something like:
class D : B {
private Tiger FrobPrivate(Square s) { ... }
public override Mammal Frob(Square s)
{
return this.FrobPrivate(s);
}
public new Tiger Frob(Square s)
{
return this.FrobPrivate(s);
}
}
Which is basically what the C# compiler would have to do on your behalf to implement the feature anyways.
I saw a C# class SomeClass that was defined like
public class SomeClass : IComparable<SomeClass>, IEquatable<SomeClass>
{
// ...
}
and I'm wondering how to translate that into English. The way I understand it seems logically impossible. How can a class inherit from a parameterized version of itself? Also, is this a common design pattern?
The key is to recognize that it's not inheriting from (or implementing) a parameterized version of itself, but rather inheriting from (or implementing) another class or interface, and using itself as a generic parameter for that target type.
For example, IComparable<T> says that there will be a CompareTo() method that takes an object of type T as a parameter. So by implementing IComparable<SomeClass> you're simply guaranteeing that a method with that signature will exist on this class:
public class SomeClass : IComparable<SomeClass>
{
public int CompareTo(SomeClass other)
{
//...
}
}
And yes, this is fairly common practice. Classes often implement the generic IComparable<> and IEquatable<> interfaces to show that they can be compared with other items of the same type. It's maybe also worth mentioning that enums in Java are declared as extending Enum<> of themselves--a pattern which is not common in C#, but does appear from time to time.
Translated in "English" it means: "Boy (or girl), you'd better be type-safe when implementing those interfaces, especially IComparable. Otherwise, you'll have to perform type casting, which I guess you don't want"
See the code below. SomeClass implemented IComparable and IComparable.
See differencies between implementations of CompareTo(object) and CompareTo(SomeClass).
namespace InterfacesStuff
{
internal class Program
{
private static void Main(string[] args)
{
var someClass1 = new SomeClass {ComparedValue = 1};
var someClass2 = new SomeClass {ComparedValue = 2};
//someClassObject defined as SomeClass
//object someClassObject = new SomeClass { ComparedValue = 2 };
//someClassObject defined as anything else but SomeClass
object someClassObject = 5;
int comparisonSomeClassBySomeClass = someClass1.CompareTo(someClass2);
int comparisonSomeClassByObject = someClass1.CompareTo(someClassObject);
}
}
public class SomeClass : IComparable, IComparable<SomeClass>, IEquatable<string>, IEquatable<int>,
IEquatable<double>
{
public int ComparedValue;
public int CompareTo(object obj)
{
var presumedSomeClassObject = obj as SomeClass;
if (presumedSomeClassObject != null)
{
if (ComparedValue <= ((SomeClass) obj).ComparedValue)
return -1;
}
return 0;
}
public int CompareTo(SomeClass other)
{
if (ComparedValue <= other.ComparedValue)
return -1;
return 0;
}
public bool Equals(double other)
{
throw new NotImplementedException();
}
public bool Equals(int other)
{
throw new NotImplementedException();
}
public bool Equals(string other)
{
throw new NotImplementedException();
}
}
}
It is not Inheriting, It is implementing the IComparable Interface. what is going on is
Someclass Implements the Icomparable and the IEquatable interface. Implementing an interface is like signing a contract stating you gaurentee that this class will implement the methods on an interface.
Icomparable msdn, IEquatable. If you look at the MSDN pages you can see that SomeClass gaurentees it will implement the methods in some fashion.
This is very common practice and it is many different names. The ones I hear most are programming by contract and Implementation over Inhertience. It lets you do a lot of cool things, like Dependency Injection, Proper Unit testing, better Generics. It does this because the compiler doesnt need to know the concrete class that your object is implementing. It just needs to know that it has certain functions on it. For further reading on this I would read Chapter one of the gang of four Design pattern book.
Wikipedia link Specifically the Introduction to Chapter one section
It doesn't really have to be convenient to express it in english for it to be valid code, although I'd probably read that as "SomeClass is comparable and equatable to itself". That doesn't really explain what's going on though, it's just a way of expressing it.
In C# types can be generic over categories of other types. Generic types are basically "type constructors". They take other types as parameters, and use them to construct new types. For instance, IEnumerable<int> and IEnumerable<string> are two completely different types. The non-generic version (IEnumerable) is a third one. In C# a type A can inherit ANY other type B as long as none of the following is true (I hope I didn't miss anything):
B is already a subtype of A
B is a class and A has already inherited another class
B is a struct
A is an interface but B is not
A is the same type as B
B is sealed
A is a struct and B is not an interface
This even makes the following code legal:
class Foo<T>
{
public T Value;
}
class Foo : Foo<int>
{
}
Foo and Foo<T> are different types, so there's no problem at all for one to inherit the other.
You can read more about generics here:
https://msdn.microsoft.com/en-us/library/ms379564(v=vs.80).aspx
And about inheritance here:
https://msdn.microsoft.com/en-us/library/ms173149.aspx
The code you posted does not inherit from any class. It is implementing certain so-called Interfaces. How to translate that snippet: "I guarantee that SomeClass will be Comparable and equatable with other SomeClass instances. I will provide definitions in this class on how to do that."
About specializing a class from some other class...
What you can do is something like this:
using System;
using System.Collections.Generic;
namespace ConsoleApp1
{
class Pet
{
protected string name;
public Pet(String name)
{
this.name = name;
}
}
class Dog : Pet
{
private List<String> tricks;
public Dog(String name, List<String> tricks):base(name)
{
this.tricks = tricks;
}
}
class Program
{
static void Main(string[] args)
{
List<string> tricks = new List<string>();
tricks.Add("sit");
tricks.Add("jump");
tricks.Add("bark");
Dog puppy = new Dog("Fido", tricks);
}
}
}
Dog inherits from Pet. Dog calls Pet's constructor at creation. Whatever name you pass into Dog constructor, it will forward it to Pet constructor.
Because what happens is that a subclass first calls the constructor of its superclass with the appropriate arguments. Then it runs its own constructor. Whatever is declared as public or protected in a class will be visible to its subclasses.
Therefore Dog will have name and also a list of tricks:
You achieve this kind of view with the "Locals" window.
I recommend that you read some tutorials on c# inheritance, interfaces and generics
Consider the following class and interfaces:
public interface A { string Property { get; set; } }
public interface B { string Property { get; set; } }
public interface C : A, B { }
public class MyClass : C
{
public string Property { get; set; }
}
Looks simple, right? Now consider the following program:
static void Main(string[] args)
{
MyClass myClass = new MyClass();
myClass.Property = "Test";
A aTest = myClass;
B bTest = myClass;
C cTest = myClass;
aTest.Property = "aTest";
System.Console.WriteLine(aTest.Property);
bTest.Property = "bTest";
System.Console.WriteLine(bTest.Property);
cTest.Property = "cTest";
System.Console.WriteLine(cTest.Property);
System.Console.ReadKey();
}
Looks okay, but it will not compile. It gives me an Ambiguity exception:
Why isn't C# able to figure this out? Is what I'm doing crazy from an architectural point of view? I'm trying to understand the why (I know it can be solved with casting).
EDIT
The problems arose when I introduced interface C. When I use MyClass : A, B I've got no problems at all.
FINAL
Just finised a blog about the subject: Interface Ambiguity and Implicit Implementation.
In short because it's ambiguous indeed.
Now more detailed story. As you've already seen there is explicit interface implementation, so you can have two different implementations for A.Property and B.Property and when you have only C there is no way you can tell if implementations are the same or not. Since C# "philosophy" is not to guess what you meant, but make you state it more clear when necessary, compiler does not choose either A.Property or B.Property, but reports an error.
You need explicit interface implementation:
public interface A { string Property { get; set; } }
public interface B { string Property { get; set; } }
public interface C : A, B { }
public class MyClass : C
{
string B.Property { get; set; }
string A.Property { get; set; }
}
When it comes time to call them you are going to have to do:
MyClass c = new MyClass();
Console.WriteLine("Property A is ": ((A)c).Property);
Why don't you do:
public class MyClass : C
{
string B.Property { get; set; }
string A.Property { get; set; }
string B { get { return B.Property; } set { B.Property=value; } }
string A { get { return A.Property; } set { A.Property=value; } }
}
And it should be noted this is bad design, if you are going to expose an interface C, make sure you find a better way to expose A/B.Property.
What's to figure out? cTest is of type "C", and it inherits "Property" from two different classes; the compiler doesn't know which one you want. This sort of behavior is inherited from C++; it's the classic example of "why multiple inheritance is a Pandora's box."
Other object-oriented languages -- Java is a notable example -- avoid this problem by definition : like-named/like-signatured methods are fused in a common descendent.
When you inherit from a single interface the compiler can determine exactly which method you are interested in implementing when you add the new method.
However when multiple interfaces have the same method, the underlying (and correct) assumption is that each interface expects a DIFFERENT implementation for the method, due to the fact that those methods or properties are defined on different interfaces.
So the compiler tells you that these different interfaces require an explicit implementation for each of these properties.
The fact that two interfaces share the same NAME for a property or method is arbitrary - there is no reason to assume that they share anything OTHER then the name, so the compiler protects you from making the mistake of implicitly treating them in the same way.
It is not simple, and it doesn't look simple either. In case of a name collision between two interfaces, .NET needs to ask you which interface are you trying to implement. Its way to ask you this is via the ambiguity error.
If you didn't have this kind of errors, you would end up implementing interfaces by chance.
you need to explicity implement both properties from each interface:
public class MyClass : C
{
string A.Property { get; set; }
string B.Property { get; set; }
}
Because what you are doing is not right. A and B are clashing and have the same name for the property... you need to use Explicit implementation of interface.
Reference here.
There are a lot of answers, and all of them are right, as explicit interface implementation is the answer to your problem.
I'll try to clarify the motivation behind this design with a somewhat convoluted example:
Let's say I have an interface for people that run (with possible implementations like LongDistanceRunner, Jogger, MarathonMan, etc)
public interface IRunner
{
void Run();
}
and an interface for devices that can be turned on and ran (with possible implementations BathTub, Application, Dishwasher, etc)
public interface IRunnable
{
void Run();
}
Now I want to create and interface for a IMusicallJogger (implementations like JoggerWithIpod,BoomBoxJogger, etc)
public interface IMusicalJogger : IRunner, IRunnable {}
public class BoomBoxJogger : IMusicalJogger
{
// code here
}
BoomBoxJogger bbJogger = new BoomBoxJogger();
Now, when I say bbJogger.Run() what should my object do? Should it start running across the park, or should it turn on the boombox, or both, or something else entirely? If I implement both the class and the callsite, it might be obvious that I want my joggers to do both, but what if I control just the callsite? And what if there are other implementations of the interface that do something else? And what if my jogger starts running across the park, when it's used in a context where it is considered like a device (through casting).
That's where explicit interface implementation comes into play.
I have to define my class like this:
public class BoomBoxJogger : IMusicalJogger
{
void IRunner.Run() //implementation of the runner aspect
{
Console.WriteLine("Running through the park");
}
void IRunnable.Run() //implementation of the runnable aspect
{
Console.WriteLine("Blasting out Megadeth on my boombox");
}
public void Run() //a new method defined in the class itself
{
Console.WriteLine("Running while listening to music");
}
}
and then, when I call, I have to specify what aspect of my jogger I want to use:
BoomBoxJogger bbJogger = new BoomBoxJogger();
((IRunner).bbJogger).Run(); // start running
((IRunnable).bbJogger).Run(); // blast the boombox
//and of course you can now do
bbJogger.Run //running while listening
((IMusicalJogger)jogger).Run(); //compiler error here, as there is no way to resolve this.
Hope I helped clarify the concept.
I am trying to find the right way to use a Generic List of Generic Interfaces as a variable.
Here is an example. It is probably not the best, but hopefully you will get the point:
public interface IPrimitive<T>
{
T Value { get; }
}
and then in another class, I want to be able to declare a variable that holds a list of objects that implement IPrimitive<T> for arbitrary T.
// I know this line will not compile because I do not define T
List<IPrimitive<T>> primitives = new List<IPrimitives<T>>;
primitives.Add(new Star()); // Assuming Star implements IPrimitive<X>
primitives.Add(new Sun()); // Assuming Sun implements IPrimitive<Y>
Note that the T in IPrimitive<T> could be different for each entry in the list.
Any ideas on how I could setup such a relationship? Alternative Approaches?
public interface IPrimitive
{
}
public interface IPrimitive<T> : IPrimitive
{
T Value { get; }
}
public class Star : IPrimitive<T> //must declare T here
{
}
Then you should be able to have
List<IPrimitive> primitives = new List<IPrimitive>;
primitives.Add(new Star()); // Assuming Star implements IPrimitive
primitives.Add(new Sun()); // Assuming Sun implements IPrimitive
John is correct.
Might I also suggest (if you are using C# 4) that you make your interface covariant?
public interface IPrimitive<out T>
{
T Value { get; }
}
This could save you some trouble later when you need to get things out of the list.
You say it won't work because you don't define T. So define it:
public class Holder<T>
{
public List<IPrimitive<T>> Primitives {get;set;}
}
This is one of the most complicated elements of the c# language though it is incredibly important for building well defined components. As such, c# falls short. However it is definitely possible to make this work.
The trick is to have 3 parts:
A non generic interface that contains all requirements of the interface.
A generic abstract class that implements the non generic interface and performs the type conversions as necessary.
A class that implements the generic abstract class with the appropriately typed results
For example:
public interface INonGenericInterface{
void Execute(object input);
object GetModel();
}
public abstract class IGenericInterfaceBase<T> : INonGenericInterface{
void INonGenericInterface.Execute(object input){
Execute((T) input);
}
object INonGenericInterface.GetModel(){
return GetModel();
}
protected abstract void Execute(T input);
protected abstract T GetModel();
}
public class ImplementingClass : IGenericInterfaceBase<ModelClass>{
protected override void Execute(ModelClass input){ /*Do something with the input */ }
protected override ModelClass GetModel(){ return new ModelClass();}
}
//Extras for demo
public class ModelClass { }
public class ModelClass2 { }
public class ImplementingClass2 : IGenericInterfaceBase<ModelClass2>
{
protected override void Execute(ModelClass2 input) { /*Do something with the input */ }
protected override ModelClass2 GetModel() { return new ModelClass2(); }
}
var agi = new INonGenericInterface[] { new ImplementingClass(), new ImplementingClass2() };
agi[0].Execute(); var model = agi[0].GetModel();
agi[1].Execute(); var model2 = agi[1].GetModel();
//Check the types of the model and model2 objects to see that they are appropriately typed.
This structure is incredibly useful when coordinating classes w/ one another because you're able to indicate that an implementing class will make use of multiple classes and have type checking validate that each class follows established type expectations. In addition, you might consider using an actual class instead of object for the non-generic class so that you can execute functions on the result of the various non-generic calls. Using this same design you can have those classes be generic classes w/ their own implementations and thus create incredibly complex applications.
To OP: Please consider changing the accepted answer to this to raise awareness of the correct approach as all previously stated answers fall short for various reasons and have probably left readers with more questions. This should handle all future questions related to generic classes in a collection.
I am currently just exposing the properties through a generic interface e.g.
public interface IBaseClass
{
int ID { get; set; }
}
internal class MyBaseClass : IBaseClass
{
public MyBaseClass() { }
public int ID { get; set; }
}
public class MyExposedClass : IBaseClass
{
private MyBaseClass _base = new MyBaseClass();
public int ID
{
get { return _base.ID; }
set { _base.ID = value; }
}
}
Then in my main application I can do:
IBaseClass c = new MyExposedClass();
c.ID = 12345;
But can't do:
MyBaseClass b = new MyBaseClass();
This is my desired behaviour.
However, I was just wondering if this is the correct approach? Or if there was a better way?
If you only want to prevent instantiation you could make MyBaseClass abstract (make it's constructor protected as well - it is a good design) and have MyExposedClass derive from it. If you want to completely hide the type your approach seems fine.
This look fine to me. Making small interfaces makes it easier to write decoupled code.
I don't know if this will help, but you can make your base class protected internal. This would mean that any internal class has access to it as if it were public, or any class (from within and without the assembly) can subclass the base class. It won't prevent people from implementing their own sub class though.
Alternatively, exposing through an Interface would be the best way I'd think.
For this you can opt for explicit implementation like this:
public interface IBaseClass
{
int ID { get; set; }
}
internal class MyBaseClass : IBaseClass
{
public MyBaseClass() { }
public int IBaseClass.ID { get; set; }
}
public class MyExposedClass : IBaseClass
{
private MyBaseClass _base = new MyBaseClass();
public int IBaseClass.ID
{
get { return _base.ID; }
set { _base.ID = value; }
}
}
You can refer to a similar post C# Interfaces. Implicit implementation versus Explicit implementation
Make your base class abstract.
You could expose the interface as public, implement an internal sealed implementation of that class, and use a factory approach to build instances of the desired interface. That way the client will never know when you change your implementation, or if you have multiple implementations of the same base interface plugged in the factory. You could also eliminate the set accessors in the interface and put them in the internal implementation to only expose the properties to the outside world. That way the exterior code has to make less assumptions over your implementation and you are better isolated. Please correct me if I'm having a poor/bad image of this approach.
Edit: The factory would be public and you'd need some sort of "transfer object" to pass data to the factory. That transfer object implementation would be public, together with it's interface.
Your example seems to include a poor example of taking advantage of inheritence. Since you included a single property it and couldnt come up with a better example i am guessing that its real. I would suggest in this case forget the base class and stick the property on the derived.