This code is compiled in visual studio, what is it's usage
public class MyClass<T>
where T : MyClass<T>
Note where T : MyClass<T>
This is the recurring template pattern and is usually used so that a base class can refer to its real type statically. This is done in an attempt to preserve type-safety so that parameter or return values referred to in the base class track the current type in the hierarchy e.g
public class Animal<T> where T : Animal<T>
{
public abstract T GiveBirth();
}
public class Cat : Animal<Cat>
{
public override Cat GiveBirth() { return new Cat(); }
}
Without the type parameter the Animal base class method would only be able to define the return type of GiveBirth to be Animal, which may reduce type safety for the clients.
It may be acceptible if you control the entire hierarchy and can ensure that classes supply the correct type parameter, but note that it can be abused e.g.
public class Cat : Animal<Dog> { ... }
Another downside is that any clients need to take account of the generic type parameter if they want to be applied to the base class e.g.
public static void Feed<T>(Animal<T> animal) where T : Animal<T> { ... }
public static void Feed<T>(T animal) where T : Animal<T> { ... }
This is an example of the curiously recurring pattern. Eric Lippert has an excellent article on this, including why you should usually avoid it.
It might be extended like this:
public class MyChild : MyClass<MyChild>
The pattern doesn't really clue you as to why you want this generic. This is unlike most generics/constraints...e.g. if I have List<Giraffe> I can see the relationship; if I have MyGeneric<T, U> where T : IComparer<U>, I can see what T will do. With T : MyClass<T>, I really have no hints as to the relationships or usages here. Perhaps there's a...
abstract T Instance { get; }
...that you wish to have the stronger-typing of MyChild in the case of MyChild.
As an example of why this isn't so good, you could have MyOtherClass : MyClass<MyChild>, or you could have MyGrandchild : MyChild, neither of which are probably what you were trying to enforce.
For types which will only have a single layer of inheritance from an abstract base type, use of the described pattern will make it possible for the abstract base type to include methods which, when called on any member of a derived type, will return a member of that derived type. This can be a useful design feature, allowing for much cleaner caller code than would otherwise be possible. The biggest problem with this design is that because .NET has no support for covariant generic class parameters, the approach won't work with multiple layers of inheritance.
Given abstract class AnimalBase<T> where T:AnimalBase<T>, with method T Clone() and class Cat: AnimalBase<Cat>, code could say var newCat = someCat.Clone(); newCat.Meow(); rather than having to say var newCat = (Cat)(someCat.Clone()); newCat.Meow();. Unfortunately, there would be no way to have a type SiameseCat properly derives from Cat, since the only way to have mySiameseCat.Clone(); return a SiameseCat would be to have SiameseCat derive from AnimalBase<SiameseCat>, but that would prevent it from deriving from Cat.
If rather than having a class constrain to its own type, one instead defines a generic interface and constrains to that, one may avoid such difficulties. There would be no problem having SiameseCat derive from Cat while implementing IAnimal<SiameseCat>. Further, interfaces are covariant, so a type which implements IAnimal<SiameseCat> could implicitly also implement IAnimal<Cat> [if Cat was an abstract type that didn't implement the interface itself]. Every derivative of the class would have to provide its own implementations of any methods whose return value varies with the generic type parameter, but from the caller's perspective, the interface types could behave perfectly with derived classes.
It looks to be guaranteeing the type is two-dimensional (if that term makes sense here).
For example: Node<int> would end up being Node<Node<int>>.
Related
What I have is a non generic interface for the purpose of having a common contact that I can call functions. The interface returns objects which implement other interfaces. For example:
public interface ISearchAdvancedInputController
{
ISearchAdvancedInput GetAdvancedInput();
void LoadFromModel(ISearchAdvancedInput advancedInput);
}
I then currently have an abstract generic class which implements the interface but imposes requirements of the type. The types of the abstract class must implement the same interfaces as the interface's properties and functions demand. I cast the generic type to the implemented type when necessary so that I can satisfy the requirements of the implemented non abstract interface. This way, I can extend this abstract class and it will enforce type requirements across a larger class w/ many different types used across it. For example:
public abstract class ISearchAdvancedInputControllerBase<standardInput, advancedInputType> : ISearchAdvancedInputController
where advancedInputType : ISearchAdvancedInput
{
protected abstract advancedInputType GetAdvancedInput();
ISearchAdvancedInput ISearchAdvancedInputController.GetAdvancedInput()
{
return GetAdvancedInput();
}
void ISearchAdvancedInputController.LoadFromModel(ISearchAdvancedInput advancedInput)
{
LoadFromModel((advancedInputType)advancedInput);
}
public abstract void LoadFromModel(advancedInputType advancedInput);
}
This works really well in general however it falls short because I'm having to use an abstract CLASS in order to perform this overriding. As such when I want to actually make use of it for more concrete examples, I encounter the error that I can only extend a single class.
So to get around this I extend the "other" class in the previous base abstract class. However this is not ideal because if I wind up creating another concrete implementation I need to redefine all of the type translations that I'm doing which is NOT related to the concrete classes implementation.
What I'd like is to not have an abstract class but instead some sort of abstract interface. If I had this I'd be able to implement concrete classes more succinctly. I've looked at other instances of this question and have tried what seems to be the main suggestion which is to make the initial interface generic and have the type extend the resulting interface type and then extend that interface with the more abstract interface as such:
interface TestGenericInterface<a> where a:TestClassInterfaceA
{
TestClassInterfaceA testGeneric { get; }
}
interface TestGenericComplexInterface<a> : TestGenericInterface<a>
where a:TestClassInterfaceA
{
new a testGeneric { get; }
}
However the concrete class seems to suffer from the same issue that's shown when you start from a non generic interface where each function / property of the base interface needs overwritten.
public class TestClass : TestGenericComplexInterface<TestGC>
{
public TestGC testGeneric => I want to complete this because its return is the type that I'm wanting to use for this concrete implementation
TestClassInterfaceA TestGenericInterface<TestGC>.testGeneric => I don't want to have to complete this because this function is already handled by the previous function in a round about sense.
}
public class TestGC : TestClassInterfaceA { }
I do see a note that I could provide default implementation of functions if I use c# v8.0 or greater, so I must be on a version prior to that but I figure this should be possible w/o that, but maybe in a different way. Hope ya'll can assist.
While expressing concern with preventing exposure of base classes, I learned (through testing) that a public class cannot inherit from an internal class; however, a public class can inherit from an internal interface. I am truly curious as to why this is possible. I believe it could be due to one of (or any combination of) the following:
An interface simply contains signatures that must be implemented.
A class may have properties, methods, etc. that can be accessed via the derived type.
A class may have methods that can be overridden by derived types.
Case 1
I believe that since an interface is simply a contract that contains signatures and states that derived types must implement those signatures, the inheritance is allowed. This is due to the fact that the interface doesn't care who accesses these signatures, only that the derived type implements them.
Case 2 and 3
Unlike interfaces, classes can have public properties that can be accessed by derived types. For example:
private class A {
public int SomeProperty { get; set; } = 0;
}
public class B : A {
// Some cool code.
}
public class C : B {
public int MyInt => SomeProperty;
}
This structure has inconsistent accessibility since SomeProperty is public and can be accessed by all derived types; thus A and B must have the same access levels to prevent exposure.
Is this the reason why a public class can derive from an internal interface but not a internal class, or am I missing something? Also, are there any other reasons why this is possible?
Note
I am not looking for an opinion based answer; I am looking for the technically correct reason why this is possible.
This is not a duplicate as I wanted the reason why you can't derive from one, but you can another.
I think that the key concept you are missing is the difference between inheritance and interface implementation.
When a class inherits another class, it means it's basically a more specific type of the base class - for instance, a dog is a specific type of an animal, so when you have classes like these:
class Animal {/* implementation here */}
class Dog : Animal {/* dog implementation here */}
The Dog class already contains all the implementation of the Animal, except it's constructors (static and instance) and Finalizers.
However, when a class implements an interface, it means that it must provide the members of said interface (namely method, properties, events and indexers), so if you have an IAnimal interface and a Dog class implementing it directly, your code looks like this:
interface IAnimal
{
void Eat();
}
class Dog : IAnimal
{
public void Eat() {/* implementation here */}
}
Note that everything that the IAnimal is declaring must be implemented, explicitly or implicitly, in the Dog class - so the contract provided by the interface is preserved in the class - regardless of whether the user of the class knows the interface or not.
So in conclusion - To use the class you don't need to know anything about the interfaces it implements, but you do need to know everything that is the class, and since a Dog IS an Animal, if the Dog is public, so must be the Animal.
The IAnimal interface, on the other hand, can stay internal.
One more point about implementing internal interfaces, already mentioned on the comments to the question by user2864740 - Since all implicit interface implementations must be public - if you are implementing an internal interface, you should consider implementing it explicitly - this way the implementation stays internal and is not exposed outside of the containing assembly.
I have the following code in C#:
1)
public class MyBinaryTree<TItem> where TItem : IComparable<TItem>
{ ... };
2)
public class MyBinaryTree<TItem> : IComparable<TItem>
{ ... };
I found this sample at this site, but it is not entirely the way I want.
The first example/code tells us that item (TItem) implements the interface IComparable.
The second example/code tells us that our whole class (MyBinaryTree) implements the interface IComparable.
I do not understand it very well.
The first example I've never used and the second I use often (this is a classic example of the interface). Some advice - supplements?
How does it apply in practice?
The difference is that the second example is interface inheritance. The second is constraints on what the generic type can be.
Interface inheritance means that the class that inherits that interface MUST provide implementations (unless it is abstract) of the methods contained within the interface. So, this essentially imposes constraints on the class and how it is built
Constraints on the other hand, impose constraints on the generic type that is used within the class. This allows the implementation to be able to make certain assumptions as to what TItem will be allowed to do within the class.
Examples:
Inheritance
public class IComparableImplemented : IComparable<T>
{
//MUST implement CompareTo
public int CompareTo(T other)
{
//Compare stuff
}
}
Type Constraints
public class ClassUsingConstraints<T> where T : IComparable<T>
{
public static void method(T stuff)
{
stuff.CompareTo(stuff);
}
}
So, you will notice that inheritance forces the class to implement a method. Whereas type constraints do not force anything on the class implementation. Instead, type constraints force that T must implement IComparable. So, that way you can rely on T having access to the CompareTo method
The statements aren't really comparable! Pun intended
One as you say is a classic implementation, the other is saying to be a valid entry in the MyBinaryTree collection, the member must implement the interface.
public class MyBinaryTree<TItem> where TItem : IComparable<TItem>
could have easily been
public class MyBinaryTree<TItem> where TItem : int;
{
}
It's only choosing to use IComparable in both statements that is leading to your furrowed brow.
I have a C# class hierarchy with a common base type and two derived types. I want to declare an abstract method on the base class something like this :
public abstract IEnumerable<T> GetSiblings<T>() where T : MyBaseClass
... and I want this method to be implemented in the derived classes such that T is the type of that derived type, for each of the derived types, ie, in derived class A:
public override IEnumerable<A> GetSiblings<A>() { ... }
... and in derived class B ...
public override IEnumerable<B> GetSiblings<B>() { ... }
Put another way, each derived class must implement the method so that it returns an IEnumerable of items of the same type. Is there any way to implement this in C# ?
Well, you can hardly call a method generic if it only accepts a parameter of a single type, and your method signatures will have different return types which isn't allowed. Why don't you define an interface for all of these classes and simply return an IEnumerable<IMyClass>?
You can't do this because the return types are different. Simple as that. The reason is if you create an instance of A and stuff it into your base class(cast it) then the return type will be wrong.
You might be able to to use new instead but that might break your hierarchy.
This is not supported by the type system. It's a common enough problem, represented often as
class Animal<T> where T : Animal<T> { }
class Cat : Animal<Cat> { } // what you desire
class Dog : Animal<Cat> { } // what is possible yet not desired
But not a problem that has as yet been acted upon by the appropriate parties (be it the framework providers or C# team, not sure who).
Until it passes the critical "worth it" test as determined by costs (and opportunity costs) versus benefits, you'll have to work around it.
I found the solution. Apparently in C# 4.0, generic parameter types can be covariant, so what I've posted above will work. C# 3.5 or lower, and it doesn't work. Took a lot of Googling.
The C# spec, section 10.1.1.1, states:
An abstract class is permitted (but
not required) to contain abstract
members.
This allows me to create classes like this:
public abstract class A
{
public void Main()
{
// it's full of logic!
}
}
Or even better:
public abstract class A
{
public virtual void Main() { }
}
public abstract class B : A
{
public override sealed void Main()
{
// it's full of logic!
}
}
This is really a concrete class; it's only abstract in so far as one can't instantiate it. For example, if I wanted to execute the logic in B.Main() I would have to first get an instance of B, which is impossible.
If inheritors don't actually have to provide implementation, then why call it abstract?
Put another way, why does C# allow an abstract class with only concrete members?
I should mention that I am already familiar with the intended functionality of abstract types and members.
Perhaps a good example is a common base class that provides shared properties and perhaps other members for derived classes, but does not represent a concrete object. For example:
public abstract class Pet
{
public string Name{get;set;}
}
public class Dog : Pet
{
public void Bark(){ ... }
}
All pets have names, but a pet itself is an abstract concept. An instance of a pet must be a dog or some other kind of animal.
The difference here is that instead of providing a method that should be overridden by implementors, the base class declares that all pets are composed of at least a Name property.
The idea is to force the implementor to derive from the class as it is intended to provide only a basis for a presumably more specialized implementation. So the base class, while not having any abstract members may only contain core methods an properties that can be used as a basis for extension.
For example:
public abstract class FourLeggedAnimal
{
public void Walk()
{
// most 4 legged animals walk the same (silly example, but it works)
}
public void Chew()
{
}
}
public class Dog : FourLeggedAnimal
{
public void Bark()
{
}
}
public class Cat : FourLeggedAnimal
{
public void Purr()
{
}
}
I think a slightly more accurate representation of your question would be: Why does C# allow an abstract class with only concrete members?
The answer: There's no good reason not to. Perhaps someone out there has some organizational structure where they like to have a noninstantiatable class at the top, even if a class below it just inherits and adds nothing. There's no good reason not to support that.
You said it -- because you can't instantiate it; it is meant to be a template only.
It is not "really a concrete class" if you declare it as abstract. That is available to you as a design choice.
That design choice may have to do with creating entities that are (at risk of mixing the terminology) abstractions of real-world objects, and with readability. You may want to declare parameters of type Car, but don't want objects to be declarable as Car -- you want every object of type Car to be instantiated as a Truck, Sedan, Coupe, or Roadster. The fact that Car doesn't require inheritors to add implementation does not detract from its value as an abstract version of its inheritors that cannot itself be instantiated.
Abstract means providing an abstraction of behaviour. For example Vehicle is an abstract form. It doesn't have any real world instance, but we can say that Vehicle has accelerating behaviour. More specifically Ford Ikon is a vehicle, and Yamaha FZ is a vehicle. Both these have accelerating behaviour.
If you now make this in the class form. Vehicle is abstract class with Acceleration method. While you may/ may not provide any abstract method. But the business need is that Vehicle should not be instantiated. Hence you make it abstract. The other two classes - Ikon and FZ are concrete classes deriving from Vehicle class. These two will have their own properties and behaviours.
With regards to usage, using abstract on a class declaration but having no abstract members is the same as having the class public but using protected on its constructors. Both force the class to be derived in order for it to be instantiated.
However, as far as self-documenting code goes, by marking the class abstract it informs others that this class is never meant to be instantiated on its own, even if it has no virtual or abstract members. Whereas protecting the constructors makes no such assertion.
The compiler does not prevent implementation-logic, but in your case I would simply omit abstract ?! BTW some methods could be implemented with { throw Exception("must inherit"); } and the compiler could not distinguish fully implemented classes and functions including only throw.
Here's a potential reason:
Layer Supertype
It's not uncommon for all the objects
in a layer to have methods you don't
want to have duplicated throughout the
system. You can move all of this
behavior into a common Layer
Supertype.
-- Martin Fowler
There's no reason to prevent having only concrete methods in an abstract class - it's just less common. The Layer Supertype is a case where this might make sense.
I see abstract classes serving two main purposes:
An incomplete class that must be specialized to provide some concrete service. Here, abstract members would be optional. The class would provide some services that the child classes can use and could define abstract members that it uses to provide its service, like in the Template Method Pattern. This type of abstract class is meant to create an inheritance hierarchy.
A class that only provides static utility methods. In this case, abstract members don't make sense at all. C# supports this notion with static classes, they are implicitly abstract and sealed. This can also be achieved with a sealed class with a private constructor.