C# 反射 转换为实例类型,用于 ex var o = (typeof(this))otherobj.

本文关键字:this otherobj var typeof ex 转换 反射 实例 类型 用于 | 更新日期: 2023-09-27 18:25:29

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;

而且不行,一些想法?感谢

抱歉:我忘了将抽象内容声明为抽象(已更正(

C# 反射 转换为实例类型,用于 ex var o = (typeof(this))otherobj.

这对

我有用

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>
{
}