public class SomeClass<T>
{
public T DoSomething()
{
var obj = Activator.CreateInstance(this.GetType());
// Do Things
return (T)obj;
}
}
public class DoStuff : SomeClass<DoStuff>
{
}
var ds = new DoStuff();
ds.DoSomething();
这有效,但在这种情况下:
public abstract class AbstractStuff : SomeClass<AbstractStuff>
{
}
public class DoStuff : AbstractStuff
{
}
var ds = new DoStuff();
ds.DoSomething();
给了我一个错误,无法实例化抽象类,我明白,我想做这样的事情:
public class SomeClass<T>
{
public T DoSomething()
{
var obj = Activator.CreateInstance(this.GetType());
// Do Things
return (my not know how to get this casting type)obj;
}
}
我试过了 返回(typeof(this((obj;
而且不行,一些想法?感谢
抱歉:我忘了将抽象内容声明为抽象(已更正(
我有用
public abstract class AbstractClass<T> where T : new()
{
public T DoSomething()
{
var obj = new T();
// Do Things
return obj;
}
}
public class DoStuff : AbstractClass<DoStuff>
{
}
var ds = new DoStuff();
ds.DoSomething();
像这样更改原始代码也是如此:
public T DoSomething()
{
var obj = Activator.CreateInstance(typeof(T));
// Do Things
return (T)obj;
}
因此,我们正在创建非抽象派生类的实例,而不是抽象基类。
考虑一下你问题中的这个例子......
public class SomeClass<T>
{
public T DoSomething()
{
var obj = Activator.CreateInstance(this.GetType());
// Do Things
return (T)obj;
}
}
。以及您有的情况
public abstract class AbstractStuff : SomeClass<AbstractStuff> { }
public class DoStuff : AbstractStuff { }
如果将类型参数替换为参数,则得到DoSomething()
public AbstractStuff DoSomething()
{
var obj = Activator.CreateInstance(this.GetType());
// Do Things
return (AbstractStuff)obj;
}
现在让我们重构一下,以便于"调试"并添加行号:
1 public AbstractStuff DoSomething()
2 {
3 var type = this.GetType();
4 var obj = Activator.CreateInstance(type);
5 // Do Things
6 return (AbstractStuff)obj;
7 }
如果在 DoStuff
的实例上调用此方法,并在第 4 行中断,您将看到type
DoStuff
;如果在第 6 行中断,您将看到obj
的运行时类型也是DoStuff
。 当然,将该对象强制转换为 AbstractStuff
将成功(甚至不需要强制转换(,因为始终存在从任何引用类型到其基类型的隐式引用转换。
现在让我们考虑您报告的错误消息:"无法实例化抽象类"。 这告诉我们什么? 它说,由于某种原因,当您调用 Activator.CreateInstance 时,您正在传递对类型 AbstractStuff
的引用。
这使得您提供给我们的示例代码似乎不准确。 GetType()
永远不能返回抽象类型,因为对象的运行时类型永远不能是抽象类型。 换句话说,不可能有一个抽象类型的实例。
事实上,如果你有这条线,你描述的行为是意料之中的......
var obj = Activator.CreateInstance(typeof(T));
。而不是...
var obj = Activator.CreateInstance(this.GetType());
你确定不是这样吗?
不能将变量强制转换为编译时未知的类型。考虑如何调用该方法:
public class Foo : SomeAbstractClass<Bar>
...
Foo foo = new Foo();
??? newFoo = foo.DoSomething();
因为Foo扩展SomeAbstractClass<Bar>
您的第一个示例希望返回Bar
,但您似乎希望返回Foo
。这只有在Bar
扩展Foo
的情况下才有可能。
你想做更多这样的事情吗?
void Main()
{
DoStuff doStuff = new DoStuff();
DoStuff doStuff2 = doStuff.DoSomething();
}
public abstract class SomeClass<T>
where T : SomeClass<T>, new()
{
public T DoSomething()
{
return new T();
}
}
public class DoStuff : SomeClass<DoStuff>
{
}