标准方法与扩展方法

时间:2010-02-28 20:28:41

标签: c#

假设以下域实体:

public enum Role
{
    User = 0,
    Moderator = 1,
    Administrator = 2
}

public class User
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public Role Role { get; set; }
}

我需要知道用户是否可以执行“编辑”操作。所以我有2个解决方案:

在用户实体

中创建CanEdit方法
public class User
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public Role Role { get; set; }

    public bool CanEdit()
    {
        return Role == Role.Moderator || Role == Role.Administrator;
    }
}

为用户类型创建CanEdit扩展方法:

public static class UserExtensions
{
    public static bool CanEdit(this User user)
    {
        return user.Role == Role.Moderator || user.Role == Role.Administrator;
    }
}

两种解决方案都有效,但问题是何时使用标准方法与使用扩展方法?

5 个答案:

答案 0 :(得分:11)

扩展方法只是普通静态方法的语法糖。

如果您控制类结构,则应在类中实现所需的所有功能。扩展方法真正有用/必要的地方是你不拥有你想要“扩展”的类。

对于这个例子,我认为你应该将逻辑放在User类中。它是用户自身的逻辑功能;消费者应该能够使用CanEdit()方法,而无需使用甚至不了解UserExtensions类。

答案 1 :(得分:2)

我大多同意Aaronaught的回答,但请考虑一下:

也许您的CanEdit()方法或其他类似方法(业务规则)可能会或多或少地发生变化,或者取决于某些外部因素。或者随着时间的推移,您将拥有越来越多的此类规则(针对不同的问题)。在这种情况下,您可能希望将它们保存在与域模型分离的不同位置,以确保域模型不具有太多不同的职责,并且不需要经常更改。

然后,一种方法是将它们作为扩展方法实现,因为这允许您将这些业务规则与您的域模型(例如User类)分开,但该方法仍然可以被User类的用户轻松发现。

实现此类业务规则的另一种方法是specification pattern,您可以将每个规则实现为单独的(规范)类,例如:在this blog post中展示。

答案 2 :(得分:1)

使用Extension方法为了使用它们没有什么意义。如果该方法属于该类,请在那里使用它。扩展方法用于扩展,在无法控制类时使用它们,或者为功能应该应用于从该接口派生的所有类的接口提供功能。

答案 3 :(得分:1)

如果你没有直接访问类的源代码,你应该使用Extensions方法,如果你有权访问源代码,我认为没有理由不使用标准方法......

答案 4 :(得分:1)

我同意Aaronaught的观点:用老式的方式实现自己的逻辑。静态方法可能导致问题(缺少使用语句,方法似乎“缺失”)。

您的模型固有的东西应该是您课程的一部分。