Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><strong>Update</strong>: Your problem is not related to the <code>yield</code> keyword specifically. It has to do with <strong>type variance</strong>.</p> <p>Your <code>AcceptChangesAndYield</code> method returns an object of a type implementing <code>IEnumerable&lt;MyModels.Interfaces.ILookup&gt;</code> (in fact it is a compiler-generated type, but that's not really important). In your method call you are trying to <em>downcast</em> this to an <code>IEnumerable&lt;MyModels.StatusLookup&gt;</code>, which is <em>more specific</em>.</p> <p>The <code>IEnumerable&lt;T&gt;</code> interface is <strong>covariant</strong> which would allow you to <em>upcast</em> to a <em>less specific</em> type; e.g., you could cast from a <code>List&lt;string&gt;</code> to an <code>IEnumerable&lt;object&gt;</code> (in .NET 4.0, anyway). The type generated by the compiler to supply the return value of your <code>AcceptChangesAndYield</code> method only implements <code>IEnumerable&lt;MyModels.Interfaces.ILookup&gt;</code>, so you could cast the result to an <code>IEnumerable&lt;object&gt;</code> (for instance), but <em>not</em> to an <code>IEnumerable&lt;MyModels.StatusLookup&gt;</code>.</p> <p>Fortunately, the solution is pretty simple. Redefine your <code>AcceptChangesAndYield</code> method as follows:</p> <pre><code>// Note: We are using a generic type constraint on T. public static IEnumerable&lt;T&gt; AcceptChangesAndYield&lt;T&gt;(this IEnumerable&lt;T&gt; obj) where T : MyModels.Interfaces.ILookup { if (obj.IsNull()) yield break; foreach (var m in obj) { // Did you mean to put m.AcceptChanges() here? yield return m; } } </code></pre> <p>This will in turn allow your <code>GetAll</code> method to be implemented as follows:</p> <pre><code>public IEnumerable&lt;MyModels.StatusLookup&gt; GetAll() { var results = Database.Current.pStatusLookupLoadAll() .ExecuteTypedList&lt;MyModels.StatusLookup&gt;(); // Note: no need for a cast, as the return value is now // already strongly typed as IEnumerable&lt;MyModels.StatusLookup&gt;. return results.AcceptChangesAndYield(); } </code></pre> <hr> <p><strong>Original Answer</strong>: It seems like you just want this?</p> <pre><code>IEnumerable&lt;T&gt; EnumerateResults&lt;T&gt;(IEnumerable&lt;T&gt; results) { if (results.IsNull()) yield break; foreach (T result in results) { // ..Common logic lines... yield return result; } } </code></pre> <p>Then in your code where you want to remove duplication, you'd just have:</p> <pre><code>// Specific stuff var results = BlahBlahBlah(); // Common stuff return EnumerateResults(results); </code></pre> <p>Right? Or am I misunderstanding your problem?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload