【问题标题】:Overloaded method calling overloaded method重载方法调用重载方法
【发布时间】:2010-09-30 04:09:55
【问题描述】:

我正在编写一个在其中调用另一个重载方法的方法。我只想写一个外部方法,因为外部方法的参数被传递给内部方法。有没有办法做到这一点?

我尝试使用泛型,但我对此知之甚少,因此无法正常工作:

public void OuterMethod<T>(T parameter)
{
    InnerMethod(parameter); // InnerMethod accepts an int or a string
}

我知道我可以做到:

public void OuterMethod(string parameter)
{
    InnerMethod(parameter);
}

public void OuterMethod(int parameter)
{
    InnerMethod(parameter);
}

但我宁愿以正确的方式执行此操作,而不是复制/粘贴代码。完成此任务的最佳方法是什么?

【问题讨论】:

    标签: c# .net overloading


    【解决方案1】:

    您可以在 C++ 中执行此操作,但不能在 C# 中执行此操作(除非内部方法也可以是泛型而不是重载)。


    或者(如果您不接受“否”作为答案),您可以在类型上进行运行时切换,例如 ...

    public void OuterMethod(object parameter)
    {
        if (parameter is int)
            InnerMethod((int)parameter);
        else if (parameter is string)
            InnerMethod((string)parameter);
        else
            throw new SomeKindOfException();
    }
    

    ...但显然这是运行时检查,而不是编译时检查。

    但我宁愿以正确的方式执行此操作,而不是复制/粘贴代码。

    您也可以编写软件来编写您的外部方法(例如,使用 System.CodeDom 类)而不是手动编写它们,但这可能比它的价值更麻烦。

    【讨论】:

      【解决方案2】:

      就像其他人说的那样,你不能真正做你想做的事,你在问题中陈述的选项是最好的选择。

      如果您使用泛型,您实际上必须转换值。否则,您可以通过接受 ChrisW 建议的对象来沮丧。

       public void OuterMethod<T>(T parameter) 
                  {
                      T temp = parameter;
                      if (temp is string )
                          InnerMethod(Convert.ToString(temp));
                      if (temp is int)
                          InnerMethod(Convert.ToInt32(temp));// InnerMethod accepts an int or a string
                  }
      

      这里是泛型概述的链接:http://msdn.microsoft.com/en-us/library/ms172193.aspx

      【讨论】:

      • 只是为可空类型(字符串但不是 int)添加它,您可以使用“as”关键字进行转换。
      • 你说,“你不能像 ChrisW 建议的那样拆箱”......你是说你不能向下转换,从对象到 int 和/或从对象到字符串?请注意,我的示例 OuterMethod 不是通用的,它的参数是 object 类型而不是 T 类型。
      【解决方案3】:

      根据您的描述,这似乎是过度优化。

      怎么样:

      public void OuterMethod(string parameter)
      {
          InnerMethod(parameter);
      }
      
      public void OuterMethod(int parameter)
      {
          InnerMethod(parameter**.ToString()**);
      }
      

      【讨论】:

        【解决方案4】:

        您可以使用dynamic 类型将重载决议推迟到运行时。

        public void OuterMethod(dynamic parameter)
        {
            InnerMethod(parameter);
        }
        
        public void InnerMethod(int parameter) { }
        public void InnerMethod(string parameter) { }
        

        警告 Expressions of type dynamic are not resolved or type checked by the compiler. 可能还会有性能损失。

        【讨论】:

          【解决方案5】:

          如果 OuterMethod 总是调用 InnerMethod,而 InnerMethod 只接受 int 或 string,那么 OuterMethod 没有任何意义。

          如果唯一的区别是一个调用 InnerMethod(int) 而另一个调用 InnerMethod(string) 你可以这样做:

          public void OuterMethod(string parameter)
          {
              InnerMethodA(parameter);
          }
          
          public void OuterMethod(int parameter)
          {
              InnerMethodA(parameter);
          }
          
          private void InnerMethodA(object parameter)
          {
              // Whatever other implementation stuff goes here
          
              if (parameter is string)
              {
                  InnerMethodB((string) parameter);
              }
              else if (parameter is int)
              {
                  InnerMethodB((string) parameter);
              }
              else
              {
                  throw new ArgumentException(...);
              }
          }
          
          private void InnerMethodB(string parameter)
          {
              // ...
          }
          
          private void InnerMethodB(int parameter)
          {
              // ...
          }
          

          【讨论】:

            【解决方案6】:

            好的,我也有类似的情况,它是我业务逻辑中的一种访问控制方法。

            有一个保存功能可以应用于我的任何持久层对象。

            看起来像这样

            public static Save<T>(AccessControl.User user,T entity) where T:PersistanceLayerBaseClass
            {
                if(CanWrite(user, entity))
                {
                    entity.save();
                }
                else
                {
                    throw new Exception("Cannot Save");
                }
            }
            

            我如何在访问控制方面为某些实体编写了一些自定义代码,所以我编写了以下内容,它寻找一种更适合使用 System.Reflection 的问题的方法,“这个实体可以由这个用户编写吗?”

            public static Boolean CanWrite<T>(AccessControl.User user, T entity) where T : PersistanceLayerBaseClass
                    {
                        int? clubId = null;
                        MethodInfo methodInfo = entity.GetType().GetMethod("CanWrite", new Type[] { typeof(AccessControl.User), entity.GetType() });
                        if(methodInfo != null)
                        {
                            return (Boolean)methodInfo.Invoke(null, new object[] { user, entity }) ;
                        }
                        else 
                        {
                            //generic answer
                        }
                        return HasRole(user.UserID, "Administrator") || (clubId.HasValue && user.MemberObject.ClubId == clubId.Value && HasRole(user.UserID, "AdministerClub"));
                    }
            

            现在每次我添加或删除一个方法时,我只需要在一个地方添加或删除它

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2022-07-18
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多