如何返回具有泛型属性的C#web服务?

如何返回具有泛型属性的C#web服务?,c#,web-services,generics,C#,Web Services,Generics,我正在创建一个web服务,并希望对返回数据更优雅一些,而不是有很多消费者需要检查的属性 根据幕后生成的数据,我需要能够返回错误数据,或者消费者期望的数据 我不希望有一个大的平面对象,并在需要时填充属性,让用户检查一个“成功”标志,而是希望一个属性Data要么是error类的实例,要么是success类的实例 这就是我想做的: class ItemResponse { public bool Success { get; set; } public T Data{ get; set

我正在创建一个web服务,并希望对返回数据更优雅一些,而不是有很多消费者需要检查的属性

根据幕后生成的数据,我需要能够返回错误数据,或者消费者期望的数据

我不希望有一个大的平面对象,并在需要时填充属性,让用户检查一个“成功”标志,而是希望一个属性Data要么是error类的实例,要么是success类的实例

这就是我想做的:

class ItemResponse
{
    public bool Success { get; set; }
    public T Data{ get; set; }
}

if( /*acceptance criteria*/ )
{
    ItemResponse<SuccessData> resp = new ItemResponse<SuccessData>();
    resp.Data = new SuccessData();
}
else
{
    ItemResponse<ErrorData> resp = new ItemResponse<ErrorData>();
    resp.Data = new ErrorData();
}

return resp;


public class SuccessData
{

}

public class ErrorData
{

}
class项目响应
{
公共bool成功{get;set;}
公共T数据{get;set;}
}
如果(/*验收标准*/)
{
ItemResponse resp=新的ItemResponse();
resp.Data=new SuccessData();
}
其他的
{
ItemResponse resp=新的ItemResponse();
resp.Data=新的ErrorData();
}
返回响应;
公共类成功数据
{
}
公共类错误数据
{
}
然后让web方法返回带有泛型属性的对象

这是可能的吗?如果是的话,鉴于webmethod返回类型必须正确键入,我该如何做呢?

简短版本,您不能按照您所建议的方式进行设置

长(er)版本第A部分

web服务可以被视为类的方法,实际上是web服务类之外的方法。我建议阅读一些web服务教程,以便更好地掌握设置web服务背后的机制。MSDN有许多特定于Microsoft堆栈的教程,可以在您喜爱的搜索引擎中轻松找到

方法的返回对象不允许具有多态行为,这本质上就是您所要求的

这个伪代码相当于您试图创建的代码,这就是编译器不允许它的原因。它不知道您正试图调用哪个
DoSomething()

class myFoo
{
     public SuccessResponse DoSomething() {....}  
     public ErrorResponse DoSomething() {....}
}
或者,您可以设想这样的情况:
public[SuccessResponse | ErrorResponse]DoSomething()

但这也是显而易见的原因。C#根本不支持多态回报

B部分 即使我们只关注
响应数据
,该对象仍然必须声明为某种类型

class Response
{
     public Collection<someType> Data;
}
现在,最终用户检查是否有错误,如果他们关心的话。假定没有错误,然后他们去查看响应数据


根据您的评论,是的,您也可以执行以下操作:

class Response
{
    public List<IYourData> Data;
    public YourEnum ReturnType;
}

public class ResponseData : IYourData { ... }  
public class ErrorData : IYourData { ... }  

WCF将为您处理
列表的序列化。它要么转换为数组,要么直接传递集合,具体取决于您的设置。有一些SO Q&A可以处理特定方面。

泛型是在编译时添加类型安全性的工具。因此,类的使用者使用的具体类型必须在编译时已知。如果你创建一个函数

List<T> myFunction<T>() {...}
…使具体类型在编译时已知。(即使您没有指定
t
,因为它可以推断,具体类型在编译时也是已知的。)


但是,您希望在
运行时
确定
数据的一般类型
:如果发生错误,则返回
项响应
,否则返回
项响应
。泛型不是这样工作的。

您可以控制使用此服务的代码吗?你能流式传输结果吗?使用JSON?我不是消费者,不是。结果需要保留为xml。web服务基本上是一个以xml形式公开的函数。因为一个函数不能有不同的类型,我不认为这可以。有一个具有一个属性的超类和两个子类会很有趣,但不确定是否允许这样做。我很确定我以前见过这样做,但我并没有任何代码来引用或验证它是否像我认为的那个样做。本质上,使用者检查成功标志,然后根据值的大小强制转换数据属性。“本质上,使用者检查成功标志,然后根据值的大小强制转换数据属性。”-我认为我看到的示例就是这样做的。为了简单起见,最好有两个对象,消费者可以首先检查是否存在错误响应。这样就不需要解释就可以使用它了。也许我之前看到的(它必须使用相同的接口用法)是过度杀戮和过度工程。出于兴趣,你能告诉我怎么做吗?感谢您写得很好的回复。@GlenH7-我编辑以修复您遇到的格式问题。您可以通过缩进四个空格来显示代码,然后显示所有特殊符号,如
,并尝试语法着色。@Bobson谢谢!我仍然在为这方面而挣扎。。。我想你也可以用
标记代替
标记,但我不是肯定的。@Bobson-在我对P.SE的编辑中(在迁移过程中死亡),我试图使用
标记,这允许
正确显示,但是,尽管使用了
标记,它还是没有显示代码格式。显然,我需要更多的练习在StackExchange上编写代码…谢谢。当我试图理解它的逻辑时,感觉有些不对劲。这里的所有答案都证实了这一点。
if( ReturnType == YourEnum.Success ) { ... }  
else if( ReturnType == YourEnum.Error ) { ... }  
else ... 
List<T> myFunction<T>() {...}
var myResult = myFunction<int>();