【问题标题】:c# inherit 2 classes at oncec#一次继承2个类
【发布时间】:2015-12-07 07:25:24
【问题描述】:

我在 C# 4.0 中遇到了一种情况,它可以从对象的多重继承中受益。

例子:

AuthorizeAttribute 和 ApiController 是 MS 标准基类。我想用我写的一个类的代码来扩展每一个,这样我就可以做到以下几点:

[AuthorizeAttributeTotalAccess]
public class TemplateController : ApiControllerBase
{
    // ...
}

public class AuthorizeAttributeTotalAccess : AuthorizeAttributeBase
{
    // ...
}

public class AuthorizeAttributeTotalAccess : AuthorizeAttributeBase
{
    protected virtual ClaimsPrincipal CurrentUser
    {
        get { return HttpContext.Current.User as ClaimsPrincipal; }
    }
    protected virtual IEnumerable<dynamic> CurrentUserClaims
    {
        get
        {
            return from c in CurrentUser.Identities.First().Claims
                    select new
                    {
                        c.Type,
                        c.Value
                    };
        }
    }

    // ...
}

public class ApiControllerBase : ApiController
{
    protected virtual ClaimsPrincipal CurrentUser
    {
        get { return HttpContext.Current.User as ClaimsPrincipal; }
    }
    protected virtual IEnumerable<dynamic> CurrentUserClaims
    {
        get
        {
            return from c in CurrentUser.Identities.First().Claims
                    select new
                    {
                        c.Type,
                        c.Value
                    };
        }
    }

    // ...
}

知道如何实现这一目标吗?如您所见,两个基类包含完全相同的代码,但每个基类必须继承不同的标准 MS 类。

【问题讨论】:

  • 只有几行代码,但您可以将它们移动到两个类都调用的单独的静态辅助方法中。
  • .NET 不支持多重继承。时期。您可以封装两个类中的一个或两个并传递方法,但不能对两者都使用纯继承。
  • 我的情况与您提供的代码类似(可能不完整)。我在我的 BaseController 中设置了一个自定义 Principal。然后,从AuthorizeAttributeTotalAccess,您可以覆盖控制器中的主体。这样一来,您就可以停止梦想多重继承,因为这是不可能的。

标签: c# asp.net-mvc inheritance custom-attributes


【解决方案1】:

这并不是完全无缝的,但是对于这种需要提供通用帮助方法的情况,您可以选择使用扩展方法。这并不是扩展方法的设计目的,因此不必将调用包装在某个共享类中的便利性被其他开发人员查看您的代码并对这些方法的来源感到困惑的潜在混淆所抵消。

public interface IUserHelperMethods
{
    // Empty marker interface
}

public static class UserHelperExtensions
{
    public static ClaimsPrincipal GetCurrentUser(this IUserHelperMethods)
    {
        return HttpContext.Current.User as ClaimsPrincipal;
    }
}

public class ApiControllerBase : ApiController, IUserHelperMethods
{
    public void Foo()
    {
        this.GetCurrentUser();
    }
}

public class AuthorizeAttributeTotalAccess : AuthorizeAttributeBase, IUserHelperMethods
{
    public void Foo()
    {
        this.GetCurrentUser();
    }
}

另外请注意,我必须将您的属性更改为 Get...() 方法,因为 C# 不支持扩展属性。

【讨论】:

  • 好答案。但是,在这种情况下,将扩展方法放在 HttpContextBase 上可能更有意义,因为它已经传递给 ApiControllerAuthorizeAttribute
  • 好点,是的 - 如果有一个现有的类型对这两种情况都是通用的,那么这是最有意义的。
【解决方案2】:

在 C# 中不能从两个类继承。这与从类继承的类继承的继承链不同。

不过,如果您查看 C# 规范,则无法解释原因。如果您与团队中的某些人交谈,他们会解释说这与在继承树上重新构建一个类有关。简而言之,它与绝对复杂性有关。

C++ 支持此功能。

仅供参考:没有计划将此功能添加到 C#。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-03
    • 1970-01-01
    • 2011-09-09
    • 2013-09-03
    • 2011-03-07
    相关资源
    最近更新 更多