Mark Allison
Mark Allison

Reputation: 7228

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.

Upvotes: 2

Views: 133

Answers (7)

HansVG
HansVG

Reputation: 779

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
}

Upvotes: 5

Paul Tsai
Paul Tsai

Reputation: 903

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)
{                
}

Upvotes: 0

Mark Bailey
Mark Bailey

Reputation: 1131

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.

Upvotes: 0

ashlar64
ashlar64

Reputation: 1094

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)
{
}

Upvotes: 0

Alexei - check Codidact
Alexei - check Codidact

Reputation: 23078

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();
    }
}

Upvotes: 0

Mike
Mike

Reputation: 435

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;
}

Upvotes: 2

Ignas
Ignas

Reputation: 4328

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
} 

Upvotes: 0

Related Questions