2

*Say I've got a class with a constructor with one required parameter and three optional ones.

public class myClass(int reqInt, string optStr1 = "st1", uint optUint1 = 0, float optFloat =0.0)
{ ... }

I know that, in my calling code, I can effectively treat this as an overloaded function, e.g.

myClass Foo = new myClass(1, "test");
myClass Foo2 = new myClass(2, "hellow world", 4);

and even

myClass Foo3 = new myClass(3, optFloat : 4.5)

What I can't figure out is how to build my parameters tuple dynamically. E.g. say my data is coming from a JSON, and I might get the following array:

[
 { "myInt" : "1"}, 
 {"myInt :"2", "myString" : "word"}, 
 {"myFloat" : "4.5", "myString" : "to" , "myInt" : "3"}, 
 {"myUInt" : "4", "myInt" "-4", "myFloat" : "4.4", "myString" : "yo!"}
]

I can obviously create 8 different callers*, but that seems like it just moves the overload from the constructor to the caller. But I can't figure out how to dynamically build the tuple, especially using named parameters/aliases, so I only have 1 calling function.

An arraylist seems like it would work, but (I think) I need to use named parameters, since there will be cases where I don't have optional parameter 1, but do have 2 or 3 (or any combinations thereof).

This can't be an edge case, but I'm not finding anything that works in my searches (I don't work in C#, or really any strongly typed languages most of the time, so forgive me if this is a really basic question).

*meaning, assume I've deserialized my Json into myJson , I could do:

If(myJson.myString.hasValue){
   if(myJson.myString.hasValue){
      if(myJson.myUInt.hasValue){
         if(myJson.myFloat.hasValue){
            (int, string, uint, float) myParams = (reqint: myJson.myInt, optStr1: myJson.myString, optUint1: myJson.myUInt, optFloat: myJson.myFloat)
         } else if
...

and so on, recursively building up the 8 possible cases. But that seems really verbose...

1
  • Perhaps this is of use? params Commented Jan 10, 2021 at 0:00

1 Answer 1

2

You could use a builder

Given

public class MyClassBuilder
{
   public int reqInt { get; set; }
   public string optStr1 { get; set; } = "st1";
   public uint optUint1 { get; set; }
   public float optFloat { get; set; }
}

Example

public class MyClass
{
   public MyClass(MyClassBuilder builder) 
     : this(builder.reqInt, builder.optStr1, builder.optUint1, builder.optFloat)
   {

   }
   public MyClass(int reqInt, string optStr1 = "st1", uint optUint1 = 0, float optFloat = 0.0f)
   {

   }
}

Usage

// Once you have deserialized to your builder, or set it somehow

var myClass = new MyClass(builder);

If your constructor options are more complicated than this, you will have to use branching in your constructor and fill out the fields manually.

Another way to achieve this, is just deserialize MyClass the way it is.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! Is there a reason that you assigned a default value to the string in the builder, but not the other optional values?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.