Tom*_* B. 6 c# generics abstract-class
我们有一个抽象类BaseClass(注意泛型arg!)和一个名为me的方法.我回来了.
如果我们在具体类中使用Me,我们将得到一个返回类型对象.然后我们必须将Me的结果转换为我们最初使用的类型.
我们怎样才能实现Me返回它的实际类型?在这个例子中输入A?
public abstract class BaseClass<TIdentifier>{
public virtual object Me{ get { return this; } }
}
public class A: BaseClass<long>
{
}
public class B: BaseClass<long>
{
}
public class controller{
public void SomeMethod(){
var a = new A();
var b = new B();
var aObject = a.Me; // this will be of type object
var aObjectCasted = (A)aObject; // cast to original
// How I want it
var aConcrete = a.Me; // this returns type a
}
}
Run Code Online (Sandbox Code Playgroud)
更新
因为有些人真的,拼命地(眨眼:-))希望了解我实际上要做的事情.
有了NHibernate,我们这样做:
var result = Session.Get<A>(idToLookUp);
Run Code Online (Sandbox Code Playgroud)
在某些情况下,由于laze加载等原因,结果不是A类型但是AProxy类型.现在如果我们想将结果转换为其他内容:我们将得到invalidcastexception,因为实际的结果类型不是但是AProxy.而且这种类型无法投放.我们只能将A类型转换为另一种类型.
此处描述了解决方法:http://sessionfactory.blogspot.be/2010/08/hacking-lazy-loaded-inheritance.html.这就是上面例子中Me属性的来源.
因此,要获得类型A的结果而不是类型AProxy,我们现在必须这样做:
var result = (A)Session.Get<A>(idToLookUp).Me;
Run Code Online (Sandbox Code Playgroud)
请注意,如果我们想要阅读并了解结果的属性,我们必须将我强制转换为类型A.
我的问题:我们可以摆脱铸造并调整Me属性,以便我们立即返回具体类型吗?
希望现在很清楚.
您可以在派生类上使用接口:
public interface IStrongTypedMe<T>
{
T Me();
}
Run Code Online (Sandbox Code Playgroud)
您的派生类将变为:
public class A: BaseClass<long>, IStrongTypedMe<A>
{
public new A Me()
{
return base.Me() as A;
}
}
Run Code Online (Sandbox Code Playgroud)
A当然,这是假设您可以更改。
更新:
我现在明白这个问题(现在只有时间阅读链接的文章)。
尝试使用扩展方法为您进行转换,如下所示:
public static TReturnType As<TReturnType,TIdentifier>(this BaseClass<TIdentifier> proxyObject)
where TReturnType : class
{
return proxyObject.Me as TReturnType;
}
Run Code Online (Sandbox Code Playgroud)
你会像这样使用它:
var result = Session.Get<A>(idToLookUp).As<A,long>();
Run Code Online (Sandbox Code Playgroud)
无需更改A或B要求。
您可以将此属性的返回类型更改为父类的定义
public abstract class BaseClass<TIdentifier>
{
public virtual BaseClass<TIdentifier> Me{ get { return this; } }
}
Run Code Online (Sandbox Code Playgroud)
如果要返回完全相同的类,可以通过在泛型类型参数中添加结果类型来进行一些解决方法
public abstract class BaseClass<TIdentifier, TMe>
where TMe : BaseClass<TIdentifier, TMe>, new()
{
public virtual TMe Me { get { return (TMe)this; } }
}
public class A : BaseClass<long, A>
{
}
Run Code Online (Sandbox Code Playgroud)