简体   繁体   English

从 C# 中的方法返回通用 class 的实例

[英]Return instance of generic class from method in C#

I have a template class:我有一个模板 class:

public abstract class Base<T> where T : IConvertible {}

And derived classes:和派生类:

public enum Vals1{}

public class Der1: Base<Vals1> {}


public enum Vals2{}

public class Der2: Base<Vals2> {}

I want to write a method that returns instance of Der1 or Der2 but I don't know which.我想编写一个返回Der1Der2实例的方法,但我不知道是哪个。

I tried something like this:我试过这样的事情:

private Base<T> GetDer() where T : IConvertible
{
    if (condition)
        return new Der1();
    return new Der2();
}

But I get errors:但我得到错误:

Cannot implicitly convert type 'Der1' to 'Base<T>'
Cannot implicitly convert type 'Der2' to 'Base<T>'

Casting doesn't help either.铸造也无济于事。 It returns the same error, just without word "implicitly".它返回相同的错误,只是没有“隐式”一词。

Is there a way to do what I want simply or do I have to find some other more strenuous way?有没有办法简单地做我想做的事,还是我必须找到其他更费力的方法?

Thanks in advance for any help.提前感谢您的帮助。

If you create an additional Base class which is not generic, then you could inherit Base<T> from it.如果您创建一个额外的Base class 不是通用的,那么您可以从它继承Base<T>

public abstract class Base {}

public abstract class Base<T> : Base where T : IConvertible {}

Then your method becomes:然后你的方法变成:

private Base GetDer()
{
    if (condition)
        return new Der1();
    return new Der2();
}

This is about finding or adding a common ancestor in the inheritance hierarchy (that is not object ...).这是关于在 inheritance 层次结构(不是object ...)中查找或添加共同祖先。 Of course, you lose information this way because you lose type information when calling GetDer() .当然,这样会丢失信息,因为在调用GetDer()时会丢失类型信息。

  • If the methods you wish to call later on your returned object do not require a value for T , then you should move those methods up from Base<T> to the Base class so that you can still use them.如果您希望稍后在返回的 object 上调用的方法不需要T的值,那么您应该将这些方法从Base<T>移动到Base class 以便您仍然可以使用它们。

  • If the methods you wish to call require a defined T , then I don't see another way than using some reflection to deduce the type of T at run-time or using the dynamic keyword to by-pass compile-time checks:如果您希望调用的方法需要定义的T ,那么除了在运行时使用一些反射来推断T的类型或使用dynamic关键字绕过编译时检查之外,我没有看到其他方法:

public abstract class Base<T> : Base where T : IConvertible {
    abstract void MethodFromBaseT();
}

...

dynamic myObject = GetDer();
myObject.MethodFromBaseT(); //does compile

Note that you have to use dynamic because the returned type is basically unknown, because as said in the comments, two different Base<T> with different T are two distinct types that do not inherit each other.请注意,您必须使用dynamic ,因为返回的类型基本上是未知的,因为正如评论中所说,具有不同T的两个不同Base<T>是两个不相互继承的不同类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM