这个新的实现将您的 cmets 考虑在内。我不介意这样说 - 这很奇怪。
第一件事 - 你必须取消派生的 getter 的泛型参数相关的静态泛型约束。你仍然可以检查这个,但它是一个运行时间。
interface IGetThing<T>
{
T Get();
}
class BaseGetter<A> : IGetThing<A> where A : new()
{
public BaseGetter()
{
var generics = this.GetType().GetGenericArguments();
for (var i = 0; i < generics.Length - 1; i++)
{
if (generics[i].BaseType != generics[i+1])
{
throw new ArgumentException(
string.Format("{0} doesn't inherit from {1}",
generics[i].FullName,
generics[i + 1].FullName));
}
}
getters = new Dictionary<Type, Func<object>>();
getters.Add(typeof(A), () => new A());
}
protected readonly IDictionary<Type, Func<object>> getters;
protected object Get(Type type)
{
var types = type.GetGenericArguments();
return getters[types[0]]();
}
public virtual A Get()
{
return (A) Get(this.GetType());
}
}
class DerivedGetter<B, A> : BaseGetter<A>, IGetThing<B>
where B : new() where A : new()
{
public DerivedGetter()
{
getters.Add(typeof(B), () => new B());
}
B IGetThing<B>.Get()
{
return (B) Get(this.GetType());
}
}
class Derived2Getter<C, B, A> : DerivedGetter<B, A>, IGetThing<C>
where C : new() where B : new() where A : new()
{
public Derived2Getter()
{
getters.Add(typeof(C), () => new C());
}
C IGetThing<C>.Get()
{
return (C) Get(this.GetType());
}
}
class Aa { }
class Bb : Aa { }
class Cc : Bb { }
class Dd { }
方法的使用(和以前一样!):
var a = new DerivedGetter();
Console.WriteLine(a.Get() is Bb);
var b = (IGetThing)a;
Console.WriteLine(b.Get() is Bb);
var c = new Derived2Getter<Cc, Bb, Aa>();
Console.WriteLine(c.Get() is Cc);
var d = (IGetThing<Bb>)c;
Console.WriteLine(d.Get() is Cc);
var e = (IGetThing<Aa>)c;
Console.WriteLine(e.Get() is Cc);
var f = new DerivedGetter<Dd, Aa>();
输出:
True
True
True
True
True
Unhandled Exception: System.ArgumentException:
ConsoleApplication16.Dd doesn't inherit from
ConsoleApplication16.Aa
下面的旧实现。
我认为您不能使用(仅)类型系统来做到这一点。您必须通过基类或派生类来实现这两个接口。
考虑到这一点,我可能会考虑通过将您想要的行为作为基类的受保护成员注入来解决此问题。
类似这样的:
接口 IGetThing
{
获取();
}
class BaseGetter<A> : IGetThing<A> where A : new()
{
protected IGetThing<A> Getter { get; set; }
public virtual A Get()
{
return Getter == null ? new A() : Getter.Get();
}
}
class DerivedGetter<B, A> : BaseGetter<A>, IGetThing<B> where B : A, new() where A : new()
{
public DerivedGetter()
{
Getter = this;
}
public override A Get()
{
return new B();
}
B IGetThing<B>.Get()
{
return (B) Get();
}
}
class Aa { }
class Bb : Aa { }
运行时,
var a = new DerivedGetter<Bb, Aa>();
Console.WriteLine(a.Get() is Bb);
var b = (IGetThing<Aa>)a;
Console.WriteLine(b.Get() is Bb);
输出:
True
True