代码之家  ›  专栏  ›  技术社区  ›  bryanjonker

接口的可选参数

  •  62
  • bryanjonker  · 技术社区  · 14 年前

    使用c#4.0——构建一个接口和一个实现该接口的类。我想在接口中声明一个可选参数,并将其反映在类中。所以,我有以下几点:

     public interface IFoo
     {
          void Bar(int i, int j=0);
     }
    
     public class Foo
     {
          void Bar(int i, int j=0) { // do stuff }
     }
    

    这个可以编译,但看起来不对。接口需要有可选参数,否则它不能正确地反映在接口方法签名中。

    我应该跳过可选参数而只使用可为null的类型吗?或者这会不会像预期的那样没有副作用或后果?

    6 回复  |  直到 14 年前
        1
  •  30
  •   pdr    14 年前

    你可以考虑可选的参数选择:

    public interface IFoo
    {
        void Bar(int i, int j);
    }
    
    public static class FooOptionalExtensions
    {
        public static void Bar(this IFoo foo, int i)
        {
            foo.Bar(i, 0);
        }
    }
    

    如果你不喜欢新语言功能的外观,你就不必使用它。

        2
  •  62
  •   Martin Brown    5 年前

    // Output:
    // 1 0
    // 2 5
    // 3 7
    namespace ScrapCSConsole
    {
        using System;
    
        interface IMyTest
        {
            void MyTestMethod(int notOptional, int optional = 5);
        }
    
        interface IMyOtherTest
        {
            void MyTestMethod(int notOptional, int optional = 7);
        }
    
        class MyTest : IMyTest, IMyOtherTest
        {
            public void MyTestMethod(int notOptional, int optional = 0)
            {
                Console.WriteLine(string.Format("{0} {1}", notOptional, optional));
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                MyTest myTest1 = new MyTest();
                myTest1.MyTestMethod(1);
    
                IMyTest myTest2 = myTest1;
                myTest2.MyTestMethod(2);
    
                IMyOtherTest myTest3 = myTest1;
                myTest3.MyTestMethod(3);
            }
        }
    }
    

    有趣的是,如果接口将参数设为可选参数,则实现该参数的类不必执行相同的操作:

    // Optput:
    // 2 5
    namespace ScrapCSConsole
    {
        using System;
    
        interface IMyTest
        {
            void MyTestMethod(int notOptional, int optional = 5);
        }
    
        class MyTest : IMyTest
        {
            public void MyTestMethod(int notOptional, int optional)
            {
                Console.WriteLine(string.Format("{0} {1}", notOptional, optional));
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                MyTest myTest1 = new MyTest();
                // The following line won't compile as it does not pass a required
                // parameter.
                //myTest1.MyTestMethod(1);
    
                IMyTest myTest2 = myTest1;
                myTest2.MyTestMethod(2);
            }
        }
    }
    

    // Optput:
    // 2 5
    namespace ScrapCSConsole
    {
        using System;
    
        interface IMyTest
        {
            void MyTestMethod(int notOptional, int optional = 5);
        }
    
        class MyTest : IMyTest
        {
            void IMyTest.MyTestMethod(int notOptional, int optional = 9)
            {
                Console.WriteLine(string.Format("{0} {1}", notOptional, optional));
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                MyTest myTest1 = new MyTest();
                // The following line won't compile as MyTest method is not available
                // without first casting to IMyTest
                //myTest1.MyTestMethod(1);
    
                IMyTest myTest2 = new MyTest();            
                myTest2.MyTestMethod(2);
            }
        }
    }
    

    Eric Lippert就这个主题写了一个有趣的系列: Optional argument corner cases

        3
  •  4
  •   Tor Haugen    10 年前

    在实现中不必使参数是可选的。您的代码将更有意义:

     public interface IFoo
     {
          void Bar(int i, int j = 0);
     }
    
     public class Foo
     {
          void Bar(int i, int j) { // do stuff }
     }
    

        4
  •  3
  •   David    12 年前

    像这样的怎么样?

    public interface IFoo
    {
        void Bar(int i, int j);
    }
    
    public static class IFooExtensions 
    {
        public static void Baz(this IFoo foo, int i, int j = 0) 
        {
            foo.Bar(i, j);
        }
    }
    
    public class Foo
    {
        void Bar(int i, int j) { /* do stuff */ }
    }
    
        5
  •  2
  •   Hitesh    9 年前

    要考虑的是当使用框架时会发生什么,这些框架是基于界面的反射而工作的。 一个问题是,没有什么可以阻止您在定义上设置不同的可选值。