I was reading a bit on generic variance and I don't have a full understanding of it yet but I'd like to know if it makes something like the following possible?
class A<T> { }
class B { }
class C : B { }
class My1 {
public My1(A<B> lessDerivedTemplateParameter)
{
}
}
class My2 : My1 {
public My2(A<C> moreDerivedTemplateParameter)
: base(moreDerivedTemplateParameter) // <-- compile error here, cannot convert
{
}
}
SAFE FOR HUMANS AND DOGS - Can-C is the first and only patented NAC eye drop that uses the exact formula proven effective in both animal and human trials, offering a non-invasive alternative to cataract surgery.
Lubricating drops for dry feeling eyes and irritation containing the potent anti-oxidant N-Acetylcarnosine (NAC), safe to be used by people with cataracts.
(IVP)'s scientists developed the lubricant eye drops (Can-C) designed as 1% N-acetylcarnosine (NAC) prodrug of L-carnosine containing a mucoadhesive cellulose-based compound combined with corneal absorption promoters in a sustained drug delivery system.
1 Lanosterol eye drops could potentially be a safe, non-invasive, and less costly alternative to cataract surgery for patients who have moderate forms of cataracts.
No, because while C
inherits from B
, A<C>
does not inherit from A<B>
.
To understand why this is the case, imagine if A<T>
were instead List<T>
:
class B { }
class C : B { }
class D : B { }
class My1 {
public My1(List<B> lessDerivedTemplateParameter)
{
// This is totally legal
lessDerivedTemplateParameter.Add(new D());
}
}
class My2 : My1 {
public My2(List<C> moreDerivedTemplateParameter)
// if this were allowed, then My1 could add a D to a list of Bs
: base(moreDerivedTemplateParameter)
{
}
}
Now on the other hand, this is legal:
interface IA<out T> {
public T GetSome();
}
class B { }
class C : B { }
class D : B { }
class My1 {
public My1(IA<B> lessDerivedTemplateParameter)
{
// This is totally legal
var someB = lessDerivedTemplateParameter.GetSome();
}
}
class My2 : My1 {
public My2(IA<C> moreDerivedTemplateParameter)
// This is allowed, because an A<C> only *produces* C's (which are also B's)
// so the base class (which consumes B's, and doesnt care if they are C's)
// can use an IA<C>
: base(moreDerivedTemplateParameter)
{
}
}
You can declare A as an interface with a contravariant type parameter and it will compile:
internal interface A<out T>
{
}
internal class B
{
}
internal class C : B
{
}
internal class My1
{
public My1(A<B> lessDerivedTemplateParameter)
{
}
}
internal class My2 : My1
{
public My2(A<C> moreDerivedTemplateParameter)
: base(moreDerivedTemplateParameter)
{
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With