【问题标题】:Changing types passed in to virtual methods更改传入虚拟方法的类型
【发布时间】:2012-01-14 04:39:33
【问题描述】:

我有一个关于在虚拟方法中更改参数类型的问题。首先我会解释一下场景。

这是可以执行命令的用户的基本界面

public interface IUserThatExecutesCommands
{
   bool IsInRole(string role);
} 

这是基本界面的扩展,需要用户有 Eminence 的概念

public interface IUserThatExecutesEminenceCommands : IUserThatExecutesCommands
{
   int Eminence { get; }
}

现在这是定义 IUserThatExecutesCommands 使用的命令的基本抽象 UserCommand 类

public abstract class UserCommand
{
   public virtual bool CanBeExecutedBy(IUserThatExecutesCommands user)
   {
       // For the purpose of simplification I have not included the actual implementation of this method.
       return UserIsInOneOfAllowedRoles(user);
   }
}

这是该类的扩展,它引入了 Eminence 的概念,因此需要 IUserThatExecutesEminenceCommands 才能使用。目前这会导致编译器错误,因为我更改了传入的使用类型。

public abstract class EminenceCommand : UserCommand
{
        public override bool CanBeExecutedBy(IUserThatExecutesEminenceCommands user)
        {
            return user.Eminence >= _requiredEminence;
        }
}

我的问题是,有没有办法可以覆盖CanBeExecutedBy 函数,以便更改传入的用户类型?我希望能够扩展 UserCommand 类,但目前由于这个问题我无法扩展。

谢谢

【问题讨论】:

    标签: c# polymorphism overriding virtual


    【解决方案1】:

    试试这个:

    public abstract class EminenceCommand : UserCommand 
    { 
            public override bool CanBeExecutedBy(IUserThatExecutesCommands user) 
            { 
                // Dynamically check the type of user passed in and only check priveleges if correct type
                IUserThatExecutesEminenceCommands u = user as IUserThatExecutesEminenceCommands;
                if( u == null) {
                     return false;
                }
                return u.Eminence >= _requiredEminence; 
            } 
    } 
    

    【讨论】:

      【解决方案2】:

      一旦您为虚拟功能建立了签名,它就成为您无法更改的合约。但是,您可以测试CanBeExecutedByuser 参数,看看它是否支持任何所需的接口。所以,你的方法应该是这样的:

      public override bool CanBeExecutedBy(IUserThatExecutesCommands user)
      {
          IUserThatExecutesEminenceCommands u = user as IUserThatExecutesEminenceCommands;
          if (u == null)
          {
              // TODO: Ignore the arg, throw an exception or do something else.
              return false;
          }
      
          return u.Eminence >= _requiredEminence;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-30
        • 1970-01-01
        • 2015-06-13
        • 1970-01-01
        • 2011-10-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多