locked
Optional argument RRS feed

  • Question

  • I need to place an optional parameter into the method, but I don't remember that it is in the interface or in the implementing class. For the moment, I place it in the interface.

     public interface ILogger
        {
            void LogTrace(string logMessage,IDictionary<string,string> dict=null);

    Monday, July 13, 2015 3:05 PM

Answers

  • A method with an optional parameter still has a parameter there that would satisfy an interface.

    You can put that =null in both or leave it out the interface.

    There are some people like one approach and some the other.

    Some say it defines intent, putting an optional parameter in the interface.

    Some people say it's just asking for the developer to set it to a different value in each and get confused.

    .

    Null doesn't seem a very useful default

    IDictionary<string,string> dict=null);

    You can null check, but an empty dictionary seems like it might be more useful to me.


    • Marked as answer by ardmore Monday, July 13, 2015 3:23 PM
    Monday, July 13, 2015 3:16 PM

All replies

  • And your question is..?

    Monday, July 13, 2015 3:10 PM
  • My question is if I have a class.

    public abstract class NLogBaseLogger : ILogger
        {
            public void LogTrace(string logMessage,IDictionary<string,string> dict)
            {
                var logger = GetLoggerFullName();
                logger.Trace(logMessage);
            }

    Or

    public abstract class NLogBaseLogger : ILogger
        {
            public void LogTrace(string logMessage,IDictionary<string,string> dict=null)
            {
                var logger = GetLoggerFullName();
                logger.Trace(logMessage);
            }
    
    // And in the interface:
    public interface ILogger
        {
            void LogTrace(string logMessage,IDictionary<string,string> dict);
    
    
    You see,  I put IDictionary<string,string> dict=null in the interface or in the class?

    Monday, July 13, 2015 3:16 PM
  • A method with an optional parameter still has a parameter there that would satisfy an interface.

    You can put that =null in both or leave it out the interface.

    There are some people like one approach and some the other.

    Some say it defines intent, putting an optional parameter in the interface.

    Some people say it's just asking for the developer to set it to a different value in each and get confused.

    .

    Null doesn't seem a very useful default

    IDictionary<string,string> dict=null);

    You can null check, but an empty dictionary seems like it might be more useful to me.


    • Marked as answer by ardmore Monday, July 13, 2015 3:23 PM
    Monday, July 13, 2015 3:16 PM
  • A class implements an interface so if you want to be able to use the optional parameter when you call a method on an object of the interface type,  the method that accepts the optional parameter must be part of the interface:

    ILogger logger = new NLogBaseLogger(...);
    //you will only be able to call methods that are defined in the ILogger interface on logger

    Note that instead of using an optional parameter, you could define two methods. One that takes the parameter and another one that doesn't. Both method still need to be part of the interface:

            public interface ILogger
            {
                void LogTrace(string logMessage, IDictionary<string, string> dict);
                void LogTrace(string logMessage);
            }

    Hope that helps.

    Please remember to close your threads by marking helpful posts as answer and then start a new thread if you have a new question. Please don't ask several questions in the same thread.

    Monday, July 13, 2015 3:21 PM
  • If you really want to use optional arguments on interfaces then you'd need to apply the default to both the interface and any class that implements it. If you don't then you end up with an inconsistent API. For example, to use the concrete type I'd have to specify the argument but using the interface I wouldn't.  Yet another scenario is the fact that the implicit interface should have the default but explicit interfaces cannot.  The C# team posted a blog article about the issues around optional arguments back when it was added.

    In general it is recommended that you do not use optional arguments except in COM interfaces. There really is no problem that they solve that cannot be solved more easily without them. For example in the case of having an optional argument on an interface you're making it easier for implementers to get it wrong. But you can accomplish the exact same thing but requiring the parameter on the interface and creating an extension method that excludes it. This also makes it easier to change the default value later if you need to.

    Michael Taylor
    http://blogs.msmvps.com/p3net

    Monday, July 13, 2015 3:34 PM