简体   繁体   中英

Can I rewrite this as a lambda expression?

I have a bit of logic in my code and I'm wondering if there's a better way of re-writing it. I have two user-defined server objects (serverA and serverB) and I want to proceed if both of them are of enum ServerType Web or Database .

Current code is clumsy:

if((serverA.ServerType == ServerType.Web || serverA.ServerType == ServerType.Database) && (serverB.ServerType == ServerType.Web || serverB.ServerType == ServerType.Database))
{
    // do stuff
}

I'm after an elegant succinct way of writing that.

I would have a new property in your user-defined server object

public class Server
{
    public ServerType ServerType { get; set; }

    public bool IsDatabaseOrWeb
    {
        get
        {
            return ServerType == ServerType.Web || ServerType == ServerType.Database;
        }            
    }
}

then your function would look like this

if (serverA.IsDatabaseOrWeb && serverB.IsDatabaseOrWeb)
{
   // do stuff
}

This way spells out more clearly that you are asking the same question about both servers and allows you to change the condition in one place if needed.

if(IsRightType(serverA) && IsRightType(serverB))
{
    // do stuff
}

bool IsRightType(Server server)
{
    return server.ServerType == ServerType.Web || server.ServerType == ServerType.Database;
}

Maybe following solution would be more elegant. Implement an abstract class so all your server objects would inherit from it.

public enum ServerType
{
    Web,
    Database,
    SomethingElse
}

public class ServerA : ServerObject
{
}

public class ServerB : ServerObject
{
}

public abstract class ServerObject
{
    public ServerType ServerType { get; set; }
}

And then implement a method for checking if an object meets your condition.

public bool IfWebOrDatabase(ServerObject so)
{
    return so.ServerType == ServerType.Web || so.ServerType == ServerType.Database;
}

And use a much shorter version of the If then.

if (IfWebOrDatabase(serverA) && IfWebOrDatabase(serverB))
{
    // do stuff
} 

A similar approach is to use extension method for enum ServerType . A possible way to write the code would be the following:

public enum ServerType
{
    Web,
    Database,
    Bi
}

public static class Extensions
{
    public static bool IsOperational(this ServerType st)
    {
        var operationalTypes  = new List<ServerType> { ServerType.Web, ServerType.Database };
        return operationalTypes.Contains(st);
    }
}

class Program
{
    static void Main(string[] args)
    {
        var st1 = ServerType.Web;
        var st2 = ServerType.Database;
        var st3 = ServerType.Bi;

        bool isSt1Operational = st1.IsOperational();
        bool isSt2Operational = st2.IsOperational();
        bool isSt3Operational = st3.IsOperational();
    }
}

Add a property to the class that contains ServerType:

public bool IsDatabaseOrWeb
{
   get
   {
      return (ServerType == ServerType.Web || ServerType == ServerType.Database);
   }
}

Then use it like:

if(ServerA.IsDatabaseOrWeb && ServerB.IsDatabaseOrWeb)
{
}

The trend you should be noticing in these answers is that the solution is worse than the problem. If you wanted to use lambda expressions in linq, it gets even worse:

if (new Server[] { serverA, serverB }.All(s => new ServerType[] { ServerType.Web, ServerType.Database }.Contains(s.ServerType)))
{ 
}

Even if you break it apart:

var badIdea = new Server[] { entity, serverB };
var alsoBad = new ServerType[] { ServerType.Web, ServerType.Database };

if (badIdea.All(s => alsoBad.Contains(s.ServerType)))
{
}

Sometimes the simplest expression is still messy. Your if statement is fine unchanged. Maybe just put a carriage return in the middle so that you can see it on the screen all at once.

Bitflags may help here.

[Flags]
public enum ServerType
{
    None = 0,
    Web=1,
    Database = 2,
    Other = 4
}

To use it

var flags = ServerType.Web | ServerType.Database;
var bothWebOrDb = (serverA.ServerType & flags) 
    & (serverB.ServerType & flags);
if (bothWebOrDb != ServerType.None)
{                
}

Which be reduced to the following

var flags = ServerType.Web | ServerType.Database;
var bothWebOrDb = serverA.ServerType & serverB.ServerType & flags;
if (bothWebOrDb != ServerType.None)
{                
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM