Last active
October 13, 2015 11:59
-
-
Save childnode/f1ea31c9489d3ce95904 to your computer and use it in GitHub Desktop.
Generics and inheritance of classes in Java and C#
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
public class BaseClass | |
{ | |
} | |
public class DerivedClassA : BaseClass | |
{ | |
} | |
class Signal<T> where T : class | |
{ | |
public void Dispatch(T obj) | |
{ } | |
} | |
class CoolSignal : Signal<Container<BaseClass>> | |
{ | |
} | |
public class Container<T> | |
where T : BaseClass | |
{ | |
} | |
public class BaseContainer : Container<BaseClass> | |
{ | |
} | |
public class DerivedContainer : Container<DerivedClassA> | |
{ | |
} | |
class TestAssignable | |
{ | |
public BaseClass DerivedAssignableToBase() | |
{ | |
return new DerivedClassA() as BaseClass; | |
} | |
public Container<BaseClass> DerivedContainerNotAssignableToBaseContainer() | |
{ | |
return new DerivedContainer() as BaseContainer; | |
} | |
} | |
class CoolMediator<T> where T : BaseClass | |
{ | |
protected Container<T> Data; | |
protected CoolSignal Signal; | |
public void Test() | |
{ | |
Signal.Dispatch(Data); | |
} | |
} | |
class CoolDerivedMediator : CoolMediator<DerivedClassA> | |
{ | |
public void Test2() | |
{ | |
Signal.Dispatch(Data); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
public class BaseClass | |
{ | |
} | |
public class DerivedClassA : BaseClass | |
{ | |
} | |
class Signal<T> where T : class | |
{ | |
public void Dispatch(T obj) | |
{ } | |
} | |
class CoolSignal : Signal<IContainer<BaseClass>> | |
{ | |
} | |
/// <summary> | |
/// using covariance | |
/// </summary> | |
internal interface IContainer<out T> | |
where T : BaseClass | |
{ | |
} | |
public class Container<T> : IContainer<T> | |
where T : BaseClass | |
{ | |
} | |
public class BaseContainer : Container<BaseClass> | |
{ | |
} | |
public class DerivedContainer : Container<DerivedClassA> | |
{ | |
} | |
class TestAssignable | |
{ | |
public BaseClass DerivedAssignableToBase() | |
{ | |
return new DerivedClassA() as BaseClass; | |
} | |
/// <summary> | |
/// not working | |
/// </summary> | |
/// <returns></returns> | |
public Container<BaseClass> DerivedContainerNotAssignableToBaseContainer() | |
{ | |
return new DerivedContainer() as BaseContainer; | |
} | |
/// <summary> | |
/// not working | |
/// </summary> | |
/// <returns></returns> | |
public IContainer<BaseClass> DerivedContainerNotAssignableToBaseContainer2() | |
{ | |
IContainer<DerivedClassA> foo = new Container<DerivedClassA>(); | |
return foo; | |
} | |
/// <summary> | |
/// not working, since a covariance is not valid for classes but only interfaces and delegates | |
/// </summary> | |
/// <returns></returns> | |
public Container<BaseClass> DerivedContainerNotAssignableToBaseContainer2() | |
{ | |
return new Container<DerivedClassA>(); | |
} | |
/// <summary> | |
/// working as of .net4 | |
/// </summary> | |
/// <returns></returns> | |
public IEnumerable<BaseClass> CovarianceExample() | |
{ | |
IEnumerable<DerivedClassA> d = new List<DerivedClassA>(); | |
IEnumerable<BaseClass> b = d; | |
return b; | |
} | |
} | |
class CoolMediator<T> where T : BaseClass | |
{ | |
protected Container<T> Data; | |
protected CoolSignal Signal; | |
public void Test() | |
{ | |
Signal.Dispatch(Data); | |
} | |
} | |
class CoolDerivedMediator : CoolMediator<DerivedClassA> | |
{ | |
public void Test2() | |
{ | |
Signal.Dispatch(Data); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Outer { | |
public class BaseClass { | |
} | |
public class DerivedClassA extends BaseClass { | |
} | |
class Signal<T> { | |
public void Dispatch(T obj) { | |
} | |
} | |
class CoolSignal extends Signal<Container<BaseClass>> { | |
} | |
public class Container<T extends BaseClass> { | |
} | |
public class BaseContainer extends Container<BaseClass> { | |
} | |
public class DerivedContainer extends Container<DerivedClassA> { | |
} | |
class TestAssignable { | |
public BaseClass DerivedAssignableToBase() { | |
return (BaseClass) (new DerivedClassA()); | |
} | |
public Container<BaseClass> DerivedContainerNotAssignableToBaseContainer() { | |
return (BaseContainer) (new DerivedContainer()); | |
} | |
} | |
class CoolMediator<T extends BaseClass> { | |
protected Container<T> Data; | |
protected CoolSignal Signal; | |
public void Test() { | |
Signal.Dispatch(Data); | |
} | |
} | |
class CoolDerivedMediator extends CoolMediator<DerivedClassA> { | |
public void Test2() { | |
Signal.Dispatch(Data); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Outer { | |
public class BaseClass { | |
} | |
public class DerivedClassA extends BaseClass { | |
} | |
class Signal<T> { | |
public void Dispatch(T obj) { | |
} | |
} | |
class CoolSignal extends Signal<Container<? extends BaseClass>> { | |
} | |
public class Container<T extends BaseClass> { | |
} | |
public class BaseContainer extends Container<BaseClass> { | |
} | |
public class DerivedContainer extends Container<DerivedClassA> { | |
} | |
class TestAssignable { | |
public BaseClass DerivedAssignableToBase() { | |
return (BaseClass) (new DerivedClassA()); | |
} | |
public Container<? extends BaseClass> DerivedContainerNotAssignableToBaseContainer() { | |
return new DerivedContainer(); | |
} | |
public Container<? extends BaseClass> DerivedContainerNotAssignableToBaseContainer2() { | |
return new Container<BaseClass>(); | |
} | |
public Container<? extends BaseClass> DerivedContainerNotAssignableToBaseContainer3() { | |
return new BaseContainer(); | |
} | |
} | |
class CoolMediator<K extends Container <? extends BaseClass>> { | |
protected K Data; | |
protected CoolSignal Signal; | |
public void Test() { | |
Signal.Dispatch(Data); | |
} | |
} | |
class CoolDerivedMediator extends CoolMediator<DerivedContainer> { | |
public void Test2() { | |
Signal.Dispatch(Data); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
some notes
what is available in Java what C# can't:
List<? extends Number>
List<?>
? super Class
TO BE DISCUSSED see
=> see GenericsAndInheritanceJavaTwo_usingWildcards.java
covariance allows what java does implicit by using bounded wildcard type
details on
what is available in C# what Java can't:
Bounded type parameter in Java
<E extends Number>
equivalents to<E> where E : Number