Returning the first method that works in a more elegant way?

I recently discovered that I am writing methods that successively call other methods and set some value based on which method first returns the corresponding value. What I did was set the value using one method and then check the value, and if that is not good, then I check the following. Here is a recent example:

private void InitContent()
{
    if (!String.IsNullOrEmpty(Request.QueryString["id"]))
    {
        Content = GetContent(Convert.ToInt64(Request.QueryString["id"]));
        ContentMode = ContentFrom.Query;
    }

    if (Content == null && DefaultId != null)
    {
        Content = GetContent(DefaultId);
        ContentMode = ContentFrom.Default;
    }

    if (Content == null) ContentMode = ContentFrom.None;
}

Here the method GetContentshould return nullif idnot in the database. This is a brief example, but you can imagine how it can become awkward if there are more options. Is there a better way to do this?

+3
source share
6 answers

- Factory . , . , . , , , ContentDefinition .

, , . - :)

+1

, .

q = W() ?? X() ?? Y() ?? Z();

, :

if ((temp = W()) == null && (temp = X()) == null && (temp == Y()) == null)
    temp = Z();
q = temp;

q W(), X(), Y(), , Z().

, .

, ; . . , .

+9

- , :

private Int64? GetContentIdOrNull(string id)
{
    return string.IsNullOrEmpty(id) ? null : (Int64?)Convert.ToInt64(id);
}

private Int64? GetContentIdOrNull(DefaultIdType id)
{
    return id;
}

private void InitContent()
{
    // Attempt to get content from multiple sources in order of preference

    var contentSources = new Dictionary<ContentFrom, Func<Int64?>> {
        { ContentFrom.Query,   () => GetContentIdOrNull(Request.QueryString["id"]) },
        { ContentFrom.Default, () => GetContentIdOrNull(DefaultId) }
    };

    foreach (var source in contentSources) {
        var id = source.Value();
        if (!id.HasValue) {
            continue;
        }

        Content = GetContent(id.Value);
        ContentMode = source.Key;

        if (Content != null) {
            return;
        }
    }

    // Default
    ContentMode = ContentFrom.None;
}

, , .

+3

, , , .

private ContentMode GetContentMode(){
}

private Content GetContent(int id){
}

private Content GetContent(HttpRequest request){
   return GetContent(Convert.ToInt64(request.QueryString["id"]));
}

private void InitContent(){
  ContentMode mode = GetContentMode();
  Content = null;
  switch(mode){
    case ContentMode.Query:
       GetContent(Request);
       break;
    case ContentMode.Default:
       GetContent(DefaultId);
       break;
    case ContentMode.None:
       ... handle none case...
       break;

  }
}

, - , . .

+2

, , ContentFrom, ,


. :)

IEnumerable<T> ValueSources()
{
     yield return _value?? _alternative;
     yield return SimpleCalculationFromCache();
     yield return ComplexCalculation();
     yield return PromptUIInputFallback("Please help by entering a value for X:");
}

T EffectiveValue { get { return ValueSources().FirstOrDefault(v => v!=null); } }

, v!=null "" .

, , , _value _alternative ""


. , , , # exe:

using System.Collections.Generic;
using System.Linq;
using System;
using T=System.String;

namespace X { public class Y
{
    public static void Main(string[]args) 
    {
        var content = Sources().FirstOrDefault(c => c); // trick: uses operator bool()
    }

    internal protected struct Content
    {
        public T Value;
        public ContentFrom Mode;
        //
        public static implicit operator bool(Content specimen) { return specimen.Mode!=ContentFrom.None && null!=specimen.Value; }
    }

    private static IEnumerable<Content> Sources()
    {
        // mock
        var Request = new { QueryString = new [] {"id"}.ToDictionary(a => a) };

        if (!String.IsNullOrEmpty(Request.QueryString["id"]))
            yield return new Content { Value = GetContent(Convert.ToInt64(Request.QueryString["id"])), Mode = ContentFrom.Query };
        if (DefaultId != null)
            yield return new Content { Value = GetContent((long) DefaultId), Mode = ContentFrom.Default };
        yield return new Content();
    }

    public enum ContentFrom { None, Query, Default };
    internal static T GetContent(long id) { return "dummy"; }
    internal static readonly long? DefaultId = 42;

} }
+1
private void InitContent()
{
    Int64? id = !String.IsNullOrEmpty(Request.QueryString["id"])
                ? Convert.ToInt64(Request.QueryString["id"])
                : null;

    if (id != null && (Content = GetContent(id)) != null)
        ContentMode = ContentFrom.Query;
    else if(DefaultId != null && (Content = GetContent(DefaultId)) != null)
        ContentMode = ContentFrom.Default;
    else
        ContentMode = ContentFrom.None;
}
0

All Articles