×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!
  • Students Click Here

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Jobs

C# Can Do Optional Parameters!

C# Can Do Optional Parameters!

C# Can Do Optional Parameters!

(OP)
Well I was suprised, but this is what I found by reflecting some VB code which had optional parameters, into C# code, and it works!

CODE

public void Foo([Optional, DefaultParameterValue(null)]string myOptionalParameter1, [Optional, DefaultParameterValue(null)]string myOptionalParameter2)
{
}

Pete

RE: C# Can Do Optional Parameters!

how does the client distinguish between parameter1 and parameter2?
example

CODE

Foo();
Foo("bar");//? is this for parameter 1 or parameter 2?
Foo("fu", "bar");
you can also use cascading members. I find this is easier to read/maintain.

CODE

public void Foo(int i)
{
   Foo(i, "");
}
public void Foo(string s))
{
   Foo(0, s);
}
public void Foo(int i, string s)
{
   //do something with i and s
}
this has has the same effect as optional parameters without obfuscating the arguments with attributes.
 

Jason Meckley
Programmer
Specialty Bakers, Inc.

RE: C# Can Do Optional Parameters!

(OP)
Well the idea is that the method will be called by something that supports optional parameters - for example, you could use it in an Excel Add-In written in C#.

That way you could call the method Foo(,"bar") when in Excel.

I agree that overloading is the better solution, but it's not possible if the arguments are all of the same type, which is a problem that I'm faced with at the moment!

Also - if you have a method with, say, 12 optional parameters and you want to convert the code into C# then you would need over 479 million methods to get all of the possible combinations.

RE: C# Can Do Optional Parameters!

I'm pretty new to c# but if you have that many optional parameters then why not use a singleton instead of passing them?

Patrick

RE: C# Can Do Optional Parameters!

because a singleton is exactly 1 instance in the entire domain. this is not an appropiate use of the pattern.

instead of having a method with 12 arguements create an immutable DTO and pass this as the argument. the other benefit is the number/types of parameters can change without changing the signature of of the method.

CODE

public void DoSomething(SimpleDtodto)
{
   string s = dto.S;
   int i = dto.I;
   DateTime d = dto.D;
}

public class SimpleDto
{
   private string s;
   private int i;
   private DateTime d;

   public SimpleDto(string s, int i, DateTime d)
   {
      this.s = s;
      this.i = i;
      this.d = d;
   }

   public string S {get {return s; }}
   public int I {get {return i; }}
   public DateTime d {get {return d; }}
}
now there is the argument that your replacing member overloads with ctor overloads. The benefit here is that now I have some options on how to manage the creation of SimpleDto.
I could make the ctor static and use inline static ctors

CODE

public class SimpleDto
{
   public static SimpleDto CreateWithInteger(int i)
   {
      return new SimpleDto(string.Empty, i, Datetime.MinValue);
   }
   public static SimpleDto CreateWithString(string s)
   {
      return new SimpleDto(s, 0, Datetime.MinValue);
   }
   public static SimpleDto CreateWithDateTime(DateTime d)
   {
      return new SimpleDto(string.Empty, 0, d);
   }

   private string s;
   private int i;
   private DateTime d;

   private SimpleDto(string s, int i, DateTime d)
   {
      this.s = s;
      this.i = i;
      this.d = d;
   }

   public string S {get {return s; }}
   public int I {get {return i; }}
   public DateTime d {get {return d; }}
}
or I could create a maping object which maps the input to a SimpleDto

CODE

interface IMapper<Input, Output>
{
   Output MapFrom(Input item);
}

class IntegerToSimpleDtoMapper : IMapper<int, SimpleDto>
{
   public SimpleDto MapFrom(int item)
   {
      return new SimpleDto(string.Empty, item, DateTime.MinValue);
   }
}
class StringToSimpleDtoMapper : IMapper<string, SimpleDto>
{
   public SimpleDto MapFrom(string item)
   {
      return new SimpleDto(item, 0, DateTime.MinValue);
   }
}

Jason Meckley
Programmer
Specialty Bakers, Inc.

RE: C# Can Do Optional Parameters!

Jason,

That looks nuts to me.

Why would you create the class explosion unless you're using a remote proxy or a webservice?  You've create a class for the hell of it.

What's wrong with public void DoSomething(string s, int i, DateTime d) in a variety of overloads or using nullable types?

C
 

RE: C# Can Do Optional Parameters!

there are more classes, but each class has a single responsibility. This makes the system more resilient to change.   

Jason Meckley
Programmer
Specialty Bakers, Inc.

RE: C# Can Do Optional Parameters!

Quote:

you can also use cascading members. I find this is easier to read/maintain.
I disagree. Bunch of overloads was never good enough for me. I prefer to have optional parameters, for the sake of simplicity.

U could use params Object[] thingie for similar effect.

I tried to use first code in C# but compailer stated errors

Quote:

how does the client distinguish between parameter1 and parameter2?
Optional parameters (OP) don't function that way. You need "named parameters" (NP). You can't skip OP, instead, you skip remaining parameters (the same thing is done with overloads but solution don't feel good to me). Using NP, u can specify parameter in any order.

RE: C# Can Do Optional Parameters!

Jason,

Each classes has a single responsibility?  I firmly disagree.  Class A still is linked to Class B.

As for adding resilience to change, I now need to open three classes, not two.

The idea of a DTO is to make a method call once to an expensive resource.  This isn't it.  
You've added a pattern because it exists, not because its needed.  Its complexity for complexities sake, or more correctly YAGNI.

C

RE: C# Can Do Optional Parameters!

Quote:

Each classes has a single responsibility?  I firmly disagree.  Class A still is linked to Class B.
What is class A & B? we may not be talking apples to apples.

Quote:

As for adding resilience to change, I now need to open three classes, not two.
using an IoC container this isn't a problem. I put all the objects into the container. When I request a given object the container will inject all the dependencies and I'm ready to go.

Quote:

The idea of a DTO is to make a method call once to an expensive resource.
that's one application, but not the only application.  I find dtos are very useful for communicating between the presentation and service layer. optional parameters (as we see here) along with other applicaitons I'm not thinking of.

Quote:

You've added a pattern because it exists, not because its needed.  Its complexity for complexities sake, or more correctly YAGNI.
I would advocate a dto is a valid option in a scenario where since there are 12 optional parameters. (can't remember where the #12 came from, but I think it was referenced above somewhere).

Jason Meckley
Programmer
Specialty Bakers, Inc.

RE: C# Can Do Optional Parameters!

J,

1)  Class A still needs to be able to call a method on class B.  It still needs to know how to pass a parameter to Class B, you've just wrapping it into Class C.  You've not gained anything.

2)  I know what you mean but what I mean is you've now altered code in 3 places.  Bad thing for testing overhead.

3)  That is the only real purpose of a DTO.  Anything else is Golden Hammer antipattern.

C

RE: C# Can Do Optional Parameters!

1. I wouldn't have class A talking to class B I would only have class A talking to interface B. The example above is simple. If it were more complex I would use a builder object to build up the optional parameters and pass the dto to the signature.

CODE

public class SimpleDtoBuilder
{
   private string s;
   private int i;
   private DateTime d;

   public SimpleDtoBuilder string String(string s)
   {
       this.s = s;
       return this;
   }
   public SimpleDtoBuilder Int(int i)
   {
       this.i = i;
       return this;
   }
   public SimpleDtoBuilder DateTime(DateTime d)
   {
       this.d = d;
       return this;
   }

   public static implicit operator SimpleDto (SimpleDtoBuilder builder)
   {
      return new SimpleDto(S, I, D);
   }
}

SimpleDto dto = new SimpleDtoBuilder
    .String("foo")
    .Int(1)
    .DateTime(DateTime.Today);

2. if the parameters within the dto are used optionally in concrete implementation then my unit tests won't change.

3. I'm skeptical when I see words like "always", "never", "only".

Jason Meckley
Programmer
Specialty Bakers, Inc.

RE: C# Can Do Optional Parameters!

1. I wouldn't have class A talking to class B I would only have class A talking to interface B. The example above is simple. If it were more complex I would use a builder object to build up the optional parameters and pass the dto to the signature.

CODE

public class SimpleDtoBuilder
{
   private string s;
   private int i;
   private DateTime d;

   public SimpleDtoBuilder string String(string s)
   {
       this.s = s;
       return this;
   }
   public SimpleDtoBuilder Int(int i)
   {
       this.i = i;
       return this;
   }
   public SimpleDtoBuilder DateTime(DateTime d)
   {
       this.d = d;
       return this;
   }

   public static implicit operator SimpleDto (SimpleDtoBuilder builder)
   {
      return new SimpleDto(S, I, D);
   }
}

SimpleDto dto = new SimpleDtoBuilder
    .String("foo")
    .Int(1)
    .DateTime(DateTime.Today);

2. if the parameters within the dto are used optionally in concrete implementation then my unit tests won't change.

3. I'm skeptical when I see words like "always", "never", "only".

Jason Meckley
Programmer
Specialty Bakers, Inc.

RE: C# Can Do Optional Parameters!

another approach is command objects. Which would negate any use of optional parameters for the object preforming the work.

CODE

interface ICommand
{
   void Execute();
}

class IntegerCommand : ICommand
{
   private int i;
   public IntegerCommand(int i)
   {
      this.i = i;
   }

   public void Execute()
   {
      //do something with i
   }
}

class StringCommand : ICommand
{
   private string s;
   public StringCommand(string s)
   {
      this.s = s;
   }

   public void Execute()
   {
      //do something with s
   }
}

class DateCommand : ICommand
{
   private DateTime d;
   public DateCommand(DateTime d)
   {
      this.d = d;
   }

   public void Execute()
   {
      //do something with d
   }
}
then you would have a command builder and command executer which would create new commands based on some specification.
return to the command and execute.

CODE

ICommand cmd = CommandBuilder.BuildUsing(...);
cmd.Execute();

Optional parameters (however supplied) would only be required in on location. wherever the command builder is located.

just another approach to the problem.

Jason Meckley
Programmer
Specialty Bakers, Inc.

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close