Generics class constraint multi level inheritance - c#

Looking for help to put such structure together.
Have base generic class:
public class A<T>
where T: class
{
public T info { get; set; }
}
Works good for one step inheritance like:
class B : A<BInfoClass>{}
But need same for higher hierarchy members like, but without making all classes generics:
class C : B<CInfoClass>{}
Need possibility to have specific "info" type for each B, C, D etc. ("info" classes derive from one base):

I'd like to suggest to add one more level of hierarchy just to make generic class to be pure generic.
You can put all common code to the AContainer also.
public class AContainer<T> where T : class, InfoA {
public T info { get; set; }
}
public class A : AContainer<InfoA> {}
public class BContainer<T>: AContainer<T> {}
public class B : BContainer<InfoB> {}
public class CContainer<T>: BContainer<T> {}
public class C : CContainer<InfoC> {}
A, B and C classes are empty classes for the without making all classes generics condition (to be used in Unity)
AContainer BContainer and CContainer are added to make generic possible here.
However it does not look like a place to use generics

Related

Choose Extended Class on Runtime C#

Good Evening to Everyone,
I have 2 abstract classes in C# :
public abstract class A
{
}
public abstract class B
{
}
I want in my third Class to decide on run time through the config file to either extend Class A or Class B.
For Example :
public Class C : B or A
Both of the abstract classes provide one abstract method with the same Signature .
No, you can't change/chose base class at run-time as base class is defined at compile time.
It sounds like implementing common interface in both classes and using just interface everywhere else would be good solution in your case.
interface IListener
{
void Listen();
...
}
class CA : A, IListener{ .... }
class CB : B, IListener { .... }
// to use:
IListner listener = useSSL ? new CA(...) : new CB(...);
If I am understanding correctly from your question and the comments (check what #RB said), the appropriate behavior would be to define:
public interface IC
{
}
public class A : IC
{
}
public class B : IC
{
}
Write your code to consume the Interface, and contrive a way to inject the correct concrete class into the consumer.

C# Derive From Generic Base Class (T : U<T>)

I am trying to find a way to derive a class from a generic base class. Say:
sealed public class Final : Base<Something>
{
}
public class Base<T> : T
where T : Anything // <-- Generics do not allow this
{
}
In C# this does not seem to be possible.
Is there any other solution to achieve something similar to this?
I found this StackOverflow question, but it doesn't seem to solve the issue, or at least I do not understand how it should.
EDIT:
The result I'd like to get is to be able to do something like that:
Anything[] anything;
//Assign some Instances to anything
foreach(Final final in anything){
//do something with final
}
The result I'd like to get is to be able to do something like that:
Anything[] anything;
//Assign some Instances to anything
foreach(Final final in anything){
//do something with final
}
Your foreach loop suggests this: class Anything : Final { … }.
This obviously turns around the inheritance hierarchy as you planned and named it. (You cannot have cycles in your inheritance relationships).
public class Base<T> : T where T : Anything { …
Let me elaborate on this part for a bit. I'll reduce your example even further to just class Base<T> : T.
This is not possible, for good reason. Imagine this:
class Base<T> : T
{
public override string Frobble()
{
Fiddle();
return "*" + base.Frobble() + "*";
}
}
class A
{
public sealed string Frobble() { … }
}
class B
{
}
class C
{
public virtual string Frobble() { … }
}
abstract class D
{
public abstract void Fiddle();
public virtual string Frobble() { … }
}
class E
{
public void Fiddle() { … }
public virtual string Frobble() { … }
}
You get all kinds of absurd situations if class Base<T> : T were allowed.
Base<A> would be absurd because Frobble cannot be overridden in a derived class.
Base<B> would be absurd because you cannot override a method that
doesn't exist in the base class.
Base<C> doesn't work because there is no Fiddle method to call.
Base<D> would not work because you cannot call an abstract method.
Only Base<E> would work.
How would the compiler ever know how to correctly compile Base<T> and analyse code that depends on it?
The point is that you cannot derive from a class that is not known at compile-time. T is a parameter, i.e. a variable, a placeholder. So class Base<T> : T is basically like saying, "Base<T> inherits from some (unknown) class". Class inheritance is a type relationship that requires both involved types to be known at compile-time. (Actually, that's not a super-precise statement because you can inherit from a generic type such as class SpecialList<T> : List<T>. But at the very least, the derived class has to know what members (methods, properties, etc.) are available in the base class.)
Is this what you want?
sealed public class Final : Base<int>{
}
public class Base<T> {
}
You could only do this if Final would be a generic class as well, like so:
public sealed class Final<T> : Base<T>
Then you can put a type restraint on T as either a class, to allow only reference types as T, or an instance of Base<T>, to allow only types that derive from Base<T>:
public class Base<T> where T : Base<T>
I don't know the context of this question, but I ran into same question with a project where I had to make it possible to extend the base class which is already derived by many others. Like:
abstract class Base {}
class FinalA : Base {}
class FinalB : Base {}
// Now create extended base class and expect final classes to be extended as well:
class BetterBase : Base {}
The solution was to create common ancestor and connect through properties:
abstract class Foundation {}
abstract class Base : Foundation
{
Foundation Final { get; }
}
class FinalA : Foundation {}
class FinalB : Foundation {}
class FinalC : Foundation
{
Foundation Base { get; }
}
// Here's the desired extension:
class BetterBase : Base {}
Now BetterBase has connection to final class and if needed, the final classes could have connection with (Better)Base also, as shown in FinalC class.

Generic base class with multiple children

I currently have a small object hierarchy that looks like this:
public class BaseClass {
// this class is empty and exists only so the others can extend it and share the
// same base type
}
public class ChildA : BaseClass {
public Subject<AssociatedClassA> Results;
}
public class ChildB : BaseClass {
public Subject<AssociatedClassB> Results;
}
In my design I would like to enforce that every class that extends from BaseClass should contain a Subject<SomeType> called Results. I'm wondering if there is a way that I can move Results into the base class or an interface such that I can supply the generic type for the Subject when constructing the base class. For example, it would be awesome if I could do something like this:
ChildA<AssociatedClassA> instance = new ChildA<AssociatedClassA>();
Or even better since there should really only be one template parameter that matches with ChildA if when I constructed it that could be taken care of for me:
ChildA instance = new ChildA();
// Results is automatically set to Subject<AssociatedClassA>
I'm stuck trying to implement this now as if I try to move Results into the base class the Subject requires a template parameter which I can't necessarily supply. There could potentially be more than 2 derived classes and I don't like the idea that someone extending this system has to know to add Results manually to each child class.
Following the suggestions of the 2 answers below this solves my desire to move Results into the base class, however I've run into another issue in that I was hoping to be able to use BaseClass as a generic parameter to methods such that any of the derived classes could be used. For example:
public void ProcessBaseClass(BaseClass base) {
// base could be ChildA or ChildB here
}
This no longer works since BaseClass now requires a type argument. Is there any way that I can have the best of both worlds here or am I stuck due to my design choices?
If appropriate, you can make the parent generic:
public class BaseClass<T> {
public Subject<T> Results;
}
public class ChildA : BaseClass<AssociatedClassA> {
}
public class ChildB : BaseClass<AssociatedClassB> {
}
You can make the base class itself generic:
public class BaseClass<T> {
public T Results { get; protected set; }
}

Does C# support multiple inheritance?

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";

Single Inheritance in C# - object class?

I have been asking myself this question for a long time now. Thought of posting it. C# doesn't support Multiple Inheritance(this is the fact). All classes created in C# derive out of 'Object' class(again a fact).
So if C# does not support Multiple inheritance, then how are we able to extend a class even though it already extends Object class?
Illustating with an example:
class A : object - Class A created.
class B : object - Class B created.
class A : B - this again is supported. What happens to the earlier association to object.
We are able to use object class methods in A after step 3. So is the turned to multi level inheritance. If that is the case, then
class A : B
class C : B
class A : C - I must be able to access class B's methods in A. Which is not the case?
Can anyone please explain?
Joel's answer is correct. There is a difference between multiple inheritance and an inhertance tree (or derivation chain). In your example, you actually show an inhertance tree: One object inherits (derives) from another object higher in the tree. Multiple inheritance allows one object to inherit from multiple base classes.
Take, for example, the following tree:
public class BaseClass { }
public class SpecialBaseClass : BaseClass {}
public class SpecialtyDerivedClass : SpecialBaseClass {}
This is perfectly valid and says that SpecialtyDerivedClass inherits from SpecialBaseClass (SpecialtyDerivedClass' parent) which, in turn, derives from BaseClass (SpecialtyDerivedClass' grandparent).
Under the idea of multiple inheritance, the example would look like this:
public class BaseClass { }
public class SpecialBaseClass {}
public class SpecialtyDerivedClass : BaseClass, SpecialBaseClass {}
This is not allowed in .NET, but it says that SpecialityDerivedClass inherits from both BaseClass and SpecialBaseClass (which are both parents).
.NET does allow a form of multiple inheritance by allowing you to inherit from more than one interface. Changing the example above slightly:
public class BaseClass { }
public interface ISpecialBase {}
public interface ISpecialDerived {}
public class SpecialtyDerivedClass : BaseClass, ISpecialBase, ISpecialDerived {}
This says that SpecialtyDerivedClass inherits from BaseClass (it's parent) and also ISpecialBase and ISpecialDerived (also parent's but more like step-parents as interfaces can't specify functionality).
You're confusing mutliple inheritance with an inheritance tree. You can inherit from something other than Object. It's just that Object is sitting way up there at the top of your tree. And someone can inherit your class, but because Object is still up there at the top that class will also inherit from object. Your "Multi-level" inheritance is not multiple inheritance.
Multiple inheritance is when you inherit from two different trees, and .Net actually does support this after a fashion via interfaces.
All classes ultimately derive from Object.
public class A
is implicitly equivalent to
public class A : System.Object
When you derive from another class
public class A : B
where
public class B : System.Object
B becomes the parent class, and Object becomes the grandparent class.
And so on.
So it is the parent, grandparent, great-grandparent (etc) class of all other classes.
One way to look at it is this: C# has an inheritance tree, while C++ (or other muliple-inheritance languages) has an inheritance lattice.
Given below.
public class A : B
{
}
public class B : C
{
public int BProperty { get; set; }
}
public class C
{
public int CProperty { get; set; }
}
public class Test
{
public void TestStuff()
{
A a = new A();
// These are valid.
a.CProperty = 1;
a.BProperty = 2;
}
}
This is valid. Object is a base for C in this case.
In the example, the reason that B can extend A is because A extends Object. A class can only specify one parent class, but that class must either be object or have object as one of its ancestors.
A class inherits from object if you do not specify a base class. Thus:
class C {}
is the same as
class C : Object {}
However, if you specify a base class, it will inherit from that class instead of Object. Thus,
class B : C {}
B directly inherits from C instead of Object. Another example,
class A : B {}
In this case, A inherits from B instead of Object. To summarize, in this hierarchy:
class C {}
class B : C {}
class A : B {}
Class A derives from B, which derives from C. So Class A is indirectly derived from C because B is derived from C. C also derived from Object which in not explicitly specified but it is there by default. So A is indirectly derived from Object too.
A class in C# can only have one parent, but it can have multiple ancestors. You can implement multiple interfaces, but that only means that your class agrees to implement the signatures defined by those interfaces. You don't actually inherit any functionality from those interfaces.

Categories

Resources