我想弄清楚如何建立一个通用的接口结构来使用流畅的符号。
我正在尝试使用如下结构:
public interface IGeneric<out T>
where T : IGeneric<T>
{
T Foo1();
T Foo2();
T Foo3();
}
public interface ISpecific_1 : IGeneric<ISpecific_1>
{ }
public interface ISpecific_2 : IGeneric<ISpecific_2>
{
ISpecific_2 Bar1();
ISpecific_2 Bar2();
ISpecific_2 Bar3();
}
public abstract class GenericImpl<T> : IGeneric<T>
where T : IGeneric<T>
{
public T Foo1()
{
//Do things
return (T)(object)this;
}
public T Foo2()
{
//Do things
return (T)(object)this;
}
public T Foo3()
{
//Do things
return (T)(object)this;
}
}
public class SpecificImpl1 : GenericImpl<ISpecific_1>, ISpecific_1
{
}
public class SpecificImpl2 : GenericImpl<ISpecific_2>, ISpecific_2
{
public ISpecific_2 Bar1()
{
//Do things
return this;
}
public ISpecific_2 Bar2()
{
//Do things
return this;
}
public ISpecific_2 Bar3()
{
//Do things
return this;
}
}
genereric只接受它自己的实现作为T,以确保Foo1(), Foo2()和Foo3()将返回正确的类型以实现流畅的符号。
GenericImpl是抽象的(不是强制性的,但我想让他们使用特定的类代替),并实现了IGeneric。
ISpecific_1用自己的类型实现了IGeneric(这意味着泛型类中的foo方法将返回ISpecific_1)。
Specific_1实现ISpecific_1并扩展GenericImpl
ISpecific_2和Specific_2相同,除了一些bar的额外方法。
这似乎可以工作,因为我可以这样做:
ISpecific_1 spec1 = new Specific_1();
spec1.Foo1().Foo2().Foo3(); //Everyone returns ISpecific_1 that extends the Generic class with the Foos
ISpecific_2 spec2 = new Specific_2();
spec2.Bar1().Foo1().Bar2().Foo2().Bar3().Foo3(); //Everyone returns ISpecific_2 with the Bars. Also the Generic Foos methods are available.
当我不能这样做时:
ISpecific_1 spec1 = new Specific_1();
spec1.Bar1().Bar2().Bar3(); //ISpecific_1 nor IGeneric don't declare Bars methods
现在的问题是:
第一个:在foo方法中,我必须通过使用
手动转换返回值return (T)(object)this;
我也可以让T: class使用
return this as T;
它们是安全的吗?还是我错过了强制转换失败的情况?
第二个:有更好的方法吗?
提前谢谢你
最后我找不到任何真正干净的解决方案:我不得不牺牲一些结构。
我让几乎所有的属性都是公共的(这对我来说不是问题);这允许我将所有方法作为泛型扩展方法而不是类方法来管理,并且它们仍然可以对公共属性进行操作。