Skip to content

Instantly share code, notes, and snippets.

@mgravell
Created September 16, 2019 06:49
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mgravell/96013fc934fd7eb2fb9cfdb589babdce to your computer and use it in GitHub Desktop.
Save mgravell/96013fc934fd7eb2fb9cfdb589babdce to your computer and use it in GitHub Desktop.
using System;
interface IFactory<out T>
{
T Create();
}
static class P
{
static void Main()
{
IFactory<Base> ambiguous = new MixedMidFactory();
Console.WriteLine(ambiguous.Create()); // MidA
ambiguous = new MixedMidFactoryReversed();
Console.WriteLine(ambiguous.Create()); // MidB
ambiguous = new MixedMidFactoryFull();
Console.WriteLine(ambiguous.Create()); // Base
ambiguous = new TwoTierFactory();
Console.WriteLine(ambiguous.Create()); // MidA
ambiguous = new TwoTierFactoryReversed();
Console.WriteLine(ambiguous.Create()); // SuperMidA
ambiguous = new TwoTierFactoryFull();
Console.WriteLine(ambiguous.Create()); // Base
}
}
class Base { }
class MidA : Base { }
class MidB : Base { }
class SuperMidA : MidA { }
// implements factories for two subclasses in separate hierarchies
class MixedMidFactory : IFactory<MidA>, IFactory<MidB>
{
MidA IFactory<MidA>.Create() => new MidA();
MidB IFactory<MidB>.Create() => new MidB();
}
// only difference to MixedMidFactory is interface declaration order
class MixedMidFactoryReversed : IFactory<MidB>, IFactory<MidA>
{
MidA IFactory<MidA>.Create() => new MidA();
MidB IFactory<MidB>.Create() => new MidB();
}
// like MixedMidFactoryReversed, but also implements the actual type requested
class MixedMidFactoryFull : IFactory<MidA>, IFactory<MidB>, IFactory<Base>
{
MidA IFactory<MidA>.Create() => new MidA();
MidB IFactory<MidB>.Create() => new MidB();
Base IFactory<Base>.Create() => new Base();
}
// implements factories for two subclasses in the same hierarchy
class TwoTierFactory : IFactory<MidA>, IFactory<SuperMidA>
{
MidA IFactory<MidA>.Create() => new MidA();
SuperMidA IFactory<SuperMidA>.Create() => new SuperMidA();
}
// only difference to TwoTierFactory is interface declaration order
class TwoTierFactoryReversed : IFactory<SuperMidA>, IFactory<MidA>
{
MidA IFactory<MidA>.Create() => new MidA();
SuperMidA IFactory<SuperMidA>.Create() => new SuperMidA();
}
// like TwoTierFactoryReversed, but also implements the actual type requested
class TwoTierFactoryFull : IFactory<SuperMidA>, IFactory<MidA>, IFactory<Base>
{
MidA IFactory<MidA>.Create() => new MidA();
SuperMidA IFactory<SuperMidA>.Create() => new SuperMidA();
Base IFactory<Base>.Create() => new Base();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment