我从我们的某个供应商那里收到了一些他们正在发布的网络服务的文档,他们非常具体地说,在他们的一个WebMethod上,一个参数有out修饰符(?不确定这是否是正确的描述符)例如,考虑以下WebMethod签名:
[WebMethod]
public void HelloWorld(out string strVal)
{
strVal = "Hello World";
}
[显然实际方法不是Hello World方法]
现在,我从未考虑使用out / ref参数设计WebMethod,它让我想知道为什么他们会使用它。
尝试理解这个设计决策的应用程序我把一个原型与几个基本的Hello World样式webmethods一起抛出...一个带有单个字符串参数,一个带有两个字符串参数,另一个没有接收任何字符串参数参数但返回一个字符串。
在尝试从单独的应用程序引用我的web方法时,我注意到我必须使用单输出字符串参数来访问该方法,就像我已经定义了输出字符串的方法一样,这实际上就客户端而言关注:
public string HelloWorld1()
{
return "Hello World";
}
和
public void HelloWorld2(out string strVal)
{
strVal = "Hello World";
}
完全相同......因为我必须同样引用它们[其中x代替正确的方法]:
string val = HelloWorldX();
尝试以我访问它们的方式引用方法,如果它们不是Web方法[如此]:
string val = string.Empty;
MyService1.HelloWorld(out val);
Console.WriteLine(val);
导致编译错误,指出没有方法参数接受1输入。这是为什么?显然有一个Web方法接受一个参数 - 我正在看它[HelloWorld2]。
在检查SOAP响应时,我注意到HelloWorld1的响应内容是:
<HelloWorld1Response xmlns="http://tempuri.org/">
<HelloWorld1Result>string</HelloWorld1Result>
</HelloWorld1Response>
HelloWorld2是
<HelloWorld2Response xmlns="http://tempuri.org/">
<strVal>string</strVal>
</HelloWorld2Response>
更进一步,我想,如果我有2个参考论点怎么办...
public void HelloWorld3(out string strVal1, out string strVal2)
{
strVal1 = "Hello World";
strVal2 = "Hello World Again!";
}
这将生成SOAP内容:
<HelloWorld3Response xmlns="http://tempuri.org/">
<strVal1>string</strVal1>
<strVal2>string</strVal2>
</HelloWorld3Response>
我认为足够公平,所以理论上[提供我可以想出一种方法来传递/ ref参数到WebMethods]这意味着我可以传入两个可以由方法设置的参数,但是当我这样做时:
string val1 = string.Empty;
string val2 = string.Empty;
MyService1.HelloWorld3(out val1,out val2);
Console.WriteLine(val1);
Console.WriteLine(val2);
当我尝试以这种方式引用HelloWorld2时,我应该得到相同的编译错误。有一个明显的例外,它抱怨2个参数而不是1 [事实上我确实得到了同样的例外,我测试了它。)
答案 0 :(得分:16)
呃......我不知道为你自己的问题提供答案的协议是什么,但Steven Behnke引用的文章提供了一些线索,让我推断出这个奇怪情况的解决方案,而不是让其他人弄清楚这意味着什么,我以为我会分享我的发现......
因此,请考虑我的WebService中定义的以下webmethod
[WebMethod]
public string Method1()
{
return "This is my return value";
}
[WebMethod]
public void Method2(out string strVal1)
{
strVal1 = "This is my value passed as an output";
//No return value
}
[WebMethod]
public void Method3(out string strVal1, out string strVal2)
{
strVal1 = "This is my strVal1 value passed as an output";
strVal2 = "This is my strVal2 value passed as an output";
//No return value
}
[WebMethod]
public string Method4(out string strVal1, out string strVal2)
{
strVal1 = "This is my strVal1 value passed as an output";
strVal2 = "This is my strVal2 value passed as an output";
return "This is my return value";
}
现在......根据文档,第一个参数定义为Out,如果方法返回void,则第一个参数自动用作返回参数。所以我会按如下方式访问我的每个方法:
方法1:公共字符串Method1(){}
var str = svc.Method1();
Console.WriteLine(str);
方法2:public void Method2(输出字符串strVal1){}
var str = svc.Method2();
Console.WriteLine(str);
所以你以完全相同的方式访问它们......这非常令人困惑。在没有被其他人告知的情况下,究竟谁会想到这一点?我无法理解这是一个好主意......
Method3:public void Method3(out string strVal1,out string strVal){}
var str2 = String.Empty;
var str1 = svc.Method3(out str2);
Console.WriteLine(str1);
Console.WriteLine(str2);
Method4:public string Method4(out string strVal1,out string strVal2){}
var str1 = String.Empty;
var str2 = String.Empty;
var str3 = svc.Method4(out str1, out str2);
Console.WriteLine(str1);
Console.WriteLine(str2);
Console.WriteLine(str3);
因此,您注意到 - 如果方法签名未提供返回值[返回void],则第一个参数将成为返回值。如果它已经提供了返回值,则它不会。
对于没有遇到该文档的人来说,这可能会非常混乱。非常感谢提供链接史蒂文 - 我真的很感激。
......对于任何人认为设计模式是写入.NET Framework的好主意 - 我想不出什么会让你认为这是一个好主意......我真的不喜欢毕竟,你非常激烈。
<强> 附录: 强>
我刚才意识到的是,如果你使用 ref 而不是 out 而增加了混乱,那么你不做这就像你使用它们在你的应用程序中调用常规方法一样对待WebMethods:
[WebMethod()]
public void Method3(ref string strVal1, ref string strVal2)
{
strVal1 = "First argument return value";
strVal2 = "Second argument return value";
}
现在打电话给你使用:
string val1 = String.Empty;
string val2 = String.Empty;
svc.Method3(ref val1, ref val2);
Console.WriteLine(val1);
Console.WriteLine(val2);
这种不一致是令人难以置信的......事实上,它的设计对我来说是不可理解的。
答案 1 :(得分:2)
也许这会有所帮助:
我最喜欢的部分是:
STATUS
此行为是设计使然。