【问题标题】:C# - Help with [Flags] Enum & Extension MethodC# - [标志] 枚举和扩展方法的帮助
【发布时间】:2010-10-06 00:06:06
【问题描述】:

我有以下枚举:

[Flags]
public enum PostAssociations
{
    None = 0x0,
    User = 0x1,
    Comments = 0x2,
    CommentsUser = 0x3
}

首先,我不确定这些标志是否正确。

我这样做是为了有一种流畅的方式来定义实体框架的“包含”(因为 EF Include 方法需要一个字符串,我不想将它暴露给 UI)。

所以我想要它,以便我的服务层可以接受 PostAssociations,并且在我的服务层中,我利用扩展方法将其转换为字符串 []。 (然后我的 repo 将其拆分以执行 .Include)。

我对 Flags Enum's 做的不多,所以我为我的无知道歉。 :)

这是我想要的“真值表”(枚举值,转换后的字符串 [])

None = null
User = new string[] { "User" }
Comments = new string[] { "Comments" }
User, Comments = new string[] { "User", "Comments" }
Comments, CommentsUser = new string[] { "Comments", "Comments.User" }
User, Comments, CommentsUser = new string[] { "User", "Comments", "Comments.User" }

不能有没有评论的评论用户。

所以我需要三件事的帮助:

  1. 如何设置枚举以匹配该真值表?
  2. 对于这些示例之一,我如何调用服务层?
  3. 如何编写扩展方法将该枚举转换为字符串数组?

当然,如果你们能想出更好的方法来做我想做的事,我也会考虑的。本质上,我试图掩盖 Enum 后面的 EF Include 的“魔术字符串”,并且考虑到您可以执行多个包含(或不包含),我认为这对于 Flags Enum 来说是一个很好的案例。

谢谢大家。

【问题讨论】:

  • 嗯,首先,0x3 绝对不是正确的值,除非您的意思是 CommentsUser 代表 UserComments 之间的联合我怀疑你实际上不想要。
  • 什么意思,没有cmets就不能有cmetsuser?
  • @Kirk Woll - 不,这不是我想要的。正如我所说,我没有使用枚举标志的经验 - 我不知道标志使用什么值。在这个阶段,除非有人想出答案,否则我会使用一系列 PostAssociations(而不是标志)。
  • @John Gardner - 正确。除非还提供了“Comments”,否则无法提供“Comments.User”(因为 .User 是 .Comments 的子集)。

标签: c# enums extension-methods flags enum-flags


【解决方案1】:

如果你创建了带有标志的枚举:

[Flags]
public enum PostAssociations
{    
    None = 0x0,
    User = 0x1,
    Comments = 0x2,
    CommentsUser = User|Comments,
}

这样会更有意义。在您当前的代码中,我不明白您要实现的目标。

否则,我认为您根本不想要基于标志的枚举...

【讨论】:

  • 是的,我认为我不应该在这里使用标志枚举。您提出的建议是有道理的,但在我的情况下(因为我没有正确解释)。 CommentsUser 是一个单独的值(不是 User + Comments)。因此,我认为我不应该使用标志。我会坚持使用 PostAssociations[]。
  • 您可以在任何枚举上使用位运算符,假设它们是 2 的幂。除非您希望 ToString 正常工作,否则您不需要 flags 属性(还有一些其他功能与之配套,但我不记得了)。
【解决方案2】:

我的坏人,我对标志枚举的缺乏经验导致了一个令人困惑的问题。

我的场景对标志枚举无效。

相反,我选择使用 PostAssociations[]。

我的服务层:

public Post FindSingle(int postId, PostAssociations[] postAssociations)
{
   return repo.Find(postAssocations.ToEfInclude()).WithId(postId);
}

扩展方法:

public static string[] ToEfInclude(this PostAssociations[] postAssocations)
{
    if (postAssocations == null) return null;

    List<string> includeAssociations = new List<string>();

    if (postAssocations.Contains(PostAssociations.User))
        includeAssociations.Add("User");
    if (postAssocations.Contains(PostAssociations.Comments))
    {
        if (postAssocations.Contains(PostAssociations.CommentsUser))
        {
            includeAssociations.Add("Comments.User");   
        }

        includeAssociations.Add("Comments");
    }

    return includeAssociations.ToArray();
}

用法:

PostAssociations[] associations = new[] { PostAssociations.Comments, PostAssociations.User, PostAssociations.CommentsUser };    
return service.Find(1, associations);

【讨论】:

  • 为了可用性,您的 FindSingle() 方法可以实现为 FindSingle(int id, params PostAssociations[] args)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-13
  • 1970-01-01
  • 2010-09-21
  • 1970-01-01
  • 1970-01-01
  • 2014-05-06
  • 1970-01-01
相关资源
最近更新 更多