【问题标题】:Using object type as a parameter使用对象类型作为参数
【发布时间】:2012-05-29 04:45:16
【问题描述】:

我一直在想:您是否支持在您的方法中仅使用 object 作为参数?我这样做的原因是超载。目前,我正在尝试创建一种适用于许多不同数据类型的方法:stringdecimalDateTime... 不胜枚举。

虽然有点乱,所以我正在考虑执行以下操作

public void GenericMethod(object val)
{
    if (val is string)
        // process as string
    else if (val is decimal)
        // process as decimal
    else if (val is DateTime)
        // do something for dt
    else
        // ...
}

您如何看待这种方法?会不会产生不必要的开销? (在类型检查期间)你实现了吗?告诉我...

编辑: 是的,只是一个旁注,我有点熟悉重载。但是当有超过 10 个重载时,它会变得有点烦人......

【问题讨论】:

  • 虽然这在技术上可行,但它肯定不是一个好主意,除非你有一个非常令人信服的理由这样做。
  • 这最终取决于您在方法中所做的事情以及您的方法对于每种类型的不同程度。理想情况下,如果它们都相似,您实际上会使用泛型并使参数泛型。如果它们完全不同,那么这绝对不是一个好主意。无法判断哪种情况适合您的情况。

标签: c# object methods parameters


【解决方案1】:

是的,那会奏效。但是有更好的方法来做到这一点。

最好的办法是使用重载:

public void GenericMethod(string val)
{
        // process as string
}
public void GenericMethod(decimal val)
{
    // process as decimal
}

等等

每当您在代码中使用 is 关键字时,这都是一个巨大的暗示,表明您可能忘记使用一些重要的 O.O.原则:重载、子类等。

重载实际上并没有那么烦人,只是为了编写。 请记住,您今天不是为自己编写代码,而是在三个月后为自己编写代码,此时您必须阅读代码并弄清楚为什么要这样做,或者这个 bug 是从哪里来的。

避免“切换类型”技术的另一个原因是为了与 .NET 框架(以及人们的期望)保持一致。关注Console.Write 以及在给定类内部和之下覆盖的其他多种方法。

【讨论】:

  • 是的,我们都经历过“你为什么要那样做”和“这个错误从哪里来”的情况。我在想其他人可能会发现只使用一种方法会更有效,而不是不得不通过许多重载来工作。
  • @matt...虽然不是。我已经习惯了 .NET 做事的方式:每种类型一个重载,如果你试图改变它,我会很困惑。
【解决方案2】:

我一直在想:您是否支持在您的方法中仅使用一个对象作为参数?

很少。如果有一组正确支持的固定类型——否则你会抛出异常——那么我会使用重载。

如果您实际上可以接受 any 类型,并且您将以某种众所周知的方式处理非特别支持的类型,那么接受object 是可以的。这就是 LINQ to XML 所做的一切,结果是一个非常干净的 API。不过,我会非常小心地这样做 - 很少是个好主意。

是的,会有开销。不过,我通常不会将其作为决定的基础——在大多数情况下,开销将小到可以忽略不计。尽可能简洁地设计您的 API,然后确定它是否会导致瓶颈。

【讨论】:

    【解决方案3】:

    是的,它会产生类型检查和装箱/拆箱值类型的开销。我会推荐重载。

    另一种可能性,只要您没有对数字进行大量数学运算,就可以将其设为通用方法。但是,使用泛型进行算术运算相当困难,因为值类型没有限制,因此可以使用运算符。

    【讨论】:

      【解决方案4】:

      不需要这些!

      只需声明尽可能多的具有相同名称的方法,并将每种类型作为每个方法的参数。[这称为重载。例如您可能已经在 Methods 旁边看到了+1 Overloads,这意味着还有 1 个 Method 同名但参数类型不同]

      这样说:

      void Method(decimal d)
      {
          //Process Decimal
      }
      void Method(string s)
      {
          //Process String
      }
      

      默认情况下,它会根据类型找到自己的方法。

      【讨论】:

        【解决方案5】:

        在某些情况下,您的方法是有意义的。我以前用过它,主要是当我有一堆对不同数据类型相同的处理时。

        但这并没有超载。重载将是为相同的方法名称定义不同的签名,如下所示:

        public void GenericMethod(string val)
        {
            // process as string
        }
        
        public void GenericMethod(decimal val)
        {
            // process as decimal
        }
        
        public void GenericMethod(DateTime val)
        {
            // do something for dt
        }
        
        // Etc.
        

        在某些情况下,这种方法更有意义。

        【讨论】:

        • 看起来意志薄弱的人已经出局了,在没有葡萄来解释原因的情况下投反对票。
        【解决方案6】:

        实现许多重载,其中一个需要object 是没有问题的。以Console.WriteLine 重载为例。 http://msdn.microsoft.com/en-us/library/system.console.writeline.aspx 但是,请注意 int 例如可能与 double 冲突:

        int sum(int i, int j)
        {
         return i + j;
        }
        
        double sum(double i, double j)
        {
         return i + j;
        }
        
        object sum(object i, object j)
        {
          return i.ToString() + j.ToString();
        }
        
        ==============================
        
        static void Main()
        {
           sum(1, 2); // Error: ambigous call between `int` and `double` versions
           sum(1.0, 2.0); // calls double version, although 1.0 and 2.0 are objects too
           sum("Hello", "World"); // object
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-12-05
          • 1970-01-01
          • 1970-01-01
          • 2013-11-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多