简体   繁体   English

我可以将其重写为lambda表达式吗?

[英]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 . 我有两个用户定义的服务器对象(serverA和serverB),如果它们都是enum ServerType WebDatabase ,我想继续。

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

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

A similar approach is to use extension method for enum ServerType . 类似的方法是对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: 将属性添加到包含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: 如果你想在linq中使用lambda表达式,它会变得更糟:

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. 你的if语句没有改变。 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. Bitflags可能会有所帮助。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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