C#泛型返回,泛型类型在方法中设置,而不是在调用中

C#泛型返回,泛型类型在方法中设置,而不是在调用中,c#,generics,C#,Generics,我正在尝试设置一个从数据库检索数据的方法,它将基于数据库中的数据创建一个带有泛型组件的类 public class MyObject<T> where T : BaseMyType { T MyTypedObject { get; set; } } public class MyType1 : BaseMyType { string Key { get; set; } } public class MyType2 : BaseMyType { Guid

我正在尝试设置一个从数据库检索数据的方法,它将基于数据库中的数据创建一个带有泛型组件的类

public class MyObject<T> where T : BaseMyType 
{
    T MyTypedObject { get; set; }
}
public class MyType1 : BaseMyType 
{
    string Key { get; set; }
}
public class MyType2 : BaseMyType 
{
    Guid Id { get; set; }
}

public MyObject<T> MyMethod<T>() where T : BaseMyType
{
    if(Situation1)
        return new MyObject(MyType1);
    else
        return new MyObject(MyType2);
}

调用当然会抱怨它无法从用法推断类型。我理解编译器错误消息,只是不确定如何执行我需要的操作。

这无法完成,但是……让我们先假设一下,我们可以找到一种方法,让下面的语句按照您想要的方式编译:

var myObject = MyMethod();
那么使用
myObject
的代码会是什么样子?在这个假设场景中,变量
myObject
有时具有类型
MyType1
,有时具有类型
MyType2
。使用
myObject
的代码是否会关心这一点

如果代码只使用共享基类型的成员(即
BaseMyType
),那么修复就很容易了。忘了一般方法吧:

public BaseMyType MyMethod()
{
    if(Situation1)
        return new MyType1();
    else
        return new MyType2();
}
如果它确实关心差异(即需要根据返回的类型访问
Key
Id
),那么即使您可以做不可能的事情,调用代码仍然需要根据
Situation1
变量有条件地处理各个场景。这意味着您将
情况1
的支票放在了错误的位置

相反,您的来电者应该更像这样:

var myObject = MyMethod();
if (Situation1)
{
    MyType1 myObject = MyMethod1();

    // do situation 1 stuff
}
else
{
    MyType2 myObject = MyMethod2();

    // do situation 2 stuff
}
原始
MyMethod()
的实现被分为两种方法,
MyMethod1()
MyMethod2()
,对应于这两种场景。再次注意,作为实现的一部分,完全没有泛型。这是不需要的,也不会起作用


您甚至可能需要调用方的多态实现,即不必多次检查
Situation1
。但是如果没有它,就不可能对这种可能性进行更彻底的评论。

考虑到编译时对这些都不了解,您根本不应该使用泛型。这对你没有帮助;这会妨碍你的。你有没有更好的建议?除了数据加载之外,任何地方都有适合我们需要的方法,我只是还没有弄清楚如何完成这一部分。为什么需要泛型?接口可能是enough@JonHelms这就是为什么不能将对象静态绑定到其成员,这意味着不使用泛型。我认为如果不想在编译时提供类型,那么应该使用
dynamic
关键字。像return
List
等。泛型用于在编译时提供类型的场景。谢谢Peter,这基本上就是我最终得到的。关键是,重要的是基类上的虚拟方法,因此泛型的父类只是一个载体。所以我声明了“starting”方法返回MyObject,然后当它调用MyBase.Validate时,它将进入特定类型。序列化仍然序列化实际类型,因此一切都很好。你的帖子非常有用。