Home>

When defining the api, for some methods that return collection objects,Many people like to define the return type as ienumerable, which is fine.Here's another question:for methods with a return type of iiumerable,We can use yield return to output the elements of the returned collection.But if we don't understand the implementation mechanism behind the yield keyword,It is likely to cause great problems.

This is a wcf related question,I think 99%of people are likely to make such mistakes-even if you know very well about yield.Less gossip,We illustrate this problem with a simple example.We define the following ideaservice interface as a service contract,The only method getitems returns an object of type inumerableand has a unique string parameter category.

[servicecontract]
 public interface idemoservice
 {
 [operationcontract]
 ienumerable<string>getitems (string category);
 }

Here is the implementation of the demoservice that implements the contract interface:the getitems method returns a collection containing 3 strings,But we need to validate the parameters before returning.If the string provided by the category parameter is null or an empty string,Throw a faultexception exception and prompt "invalid category", so that the client can get an error message in the case of entering invalid parameters.This way of programming can't be more normal,Isn't it?

public class demoservice:idemoservice
{
 public ienumerable<string>getitems (string categoty)
 {
 if (string.isnullorempty (categoty))
 {
 throw new faultexception ("invalid category");
 }
 yield return "foo";
 yield return "bar";
 yield return "baz";
 }
}

But normal does n’t mean correct.The client actually cannot get the error message provided to it by the server,The following is the error obtained when the client calls the service and specifies an empty string parameter.A communication exception is thrown,I get the error message "an error occurred while receiving the http response to http://127.0.0.1:3721/demoservice. This could be due to the service endpoint binding not using the http protocol. This could also be due to an http request context being aborted by the server (possibly due to the service shutting down). see server logs for more details. "

This looks different from what we expected,What we want is that the client throws a faultexception and prompts "invalid category". This is actually because "yield" is at work, if you don't believe it, you can replace the getitems method defined in demoservice with the following definitionThat is, directly return a string [] object.

public class demoservice:idemoservice
{
 public ienumerable<string>getitems (string categoty)
 {
 if (string.isnullorempty (categoty))
 {
 throw new faultexception ("invalid category");
 }
 return new string [] {"foo", "bar", "baz"};
 }
}

Run our program again,This time we can get the results we expected.

Interested friends can think about why the two seemingly equivalent ways have completely different results,See [Part 2] for specific reasons.

c
  • Previous Analysis of multiple methods of passing values ​​between C # Winform windows
  • Next winform control input method