-2

I am trying to recreate in C# this elegant builder pattern that I found in the book "Efective Java", but I am not expert in C#.

// Builder Pattern


public class NutritionFacts { 

    private final int calories; 
    private final int fat; 
    private final int sodium; 
    private final int carbohydrate;

    public static class Builder { 
        // Optional parameters - initialized to default values 
        private int calories = 0; 
        private int fat = 0; 
        private int carbohydrate = 0; 
        private int sodium = 0;

        public Builder();
        public Builder calories(int val) { calories = val; return this; } 
        public Builder fat(int val) { fat = val; return this; } 
        public Builder carbohydrate(int val) { carbohydrate = val; return this;} 
        public Builder sodium(int val) { sodium = val; return this; }

        public NutritionFacts build() { 
            return new NutritionFacts(this); 
        }
    }
    private NutritionFacts(Builder builder) { 
        calories = builder.calories; 
        fat = builder.fat; 
        sodium = builder.sodium; 
        carbohydrate = builder.carbohydrate; 
        }
}

With this Builder you can create the NutritionFacts object like this, providing the constructor parameters one by one:

NutritionFacts cocaCola = new NutritionFacts.Builder(). calories(100).sodium(35).carbohydrate(27).build();

However seems that in C# non-static parameters are not allowed in a static nested class. So, how could I translate this to C#?

Thanks in advance.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
Chemari
  • 43
  • 7
  • What do you mean by "non-static parameters"? The term "static" only applies to class members, not to function parameters, so I'm unclear what you are referring to. – Code-Apprentice Oct 30 '18 at 17:56
  • 2
    Also, you should make an attempt to translate the Java code into C#. If you encounter problems along the way, you can post a question with your code and describe the problem, including any errors. – Code-Apprentice Oct 30 '18 at 17:57
  • Sorry, I meant variables, nor parameters. Let me fix it... – Chemari Oct 30 '18 at 17:58
  • 1
    I think the trick would be to not have `Builder` be static. Not sure about what black magic in Java allows you to instantiate a static class. – juharr Oct 30 '18 at 18:03
  • 2
    @juharr In Java a class being static has nothing to do with whether that class' members are instance or static, but on whether the nested class has an implicit reference to the containing class. – Servy Oct 30 '18 at 18:05
  • I think the duplicate should be quite on point. Don't mind to @-reply me if it's not. – Camilo Terevinto Oct 30 '18 at 18:06
  • 1
    That style isn't very idiomatic in C#. But, as you found, a `static` class in C# can only have static members. It cannot be instantiated. Instead, what you want it to have is a non-static class (you are instantiating one and setting instance state after-all). If you remove the `static` from the `class Builder`, it seems like it should work. C# programmers, by the way, will expect that the public methods of your classes (calories through build) will be capitalized - as a matter of language-specific style. – Flydog57 Oct 30 '18 at 18:06
  • And, for what it's worth, the way you typically do this in C# is to make a class have public properties (initialized with defaults). Then, you create an instance this way `var myInstance = new MyClass {Prop1 = value1, Prop2 = value2, PropN = valueN };` – Flydog57 Oct 30 '18 at 18:09
  • By the way, I just tried an online Java > C# converted and gave me the exact code you should be using... – Camilo Terevinto Oct 30 '18 at 18:12

1 Answers1

-3

One solution is to pull the Builder class outside of the NutritionFacts class. You might also change the name to NutritionFacstBuilder.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • 2
    How does this fix any of the problems the question is asking about? – Servy Oct 30 '18 at 18:02
  • @Servy In Java, a top-level class cannot be declared "static". So the implication behind my answer is that "static" would be removed. It seems that in this context, "static" means two very different things in Java and C#. – Code-Apprentice Oct 30 '18 at 18:12
  • Yes, that's true. You've now also failed to answer my question, in addition to failing to answer the OP's question. – Servy Oct 30 '18 at 18:13
  • @Servy I guess I don't understand why a top-level non-static class **won't** solve the problem? – Code-Apprentice Oct 30 '18 at 18:20
  • You can solve the problem equally effectively whether the class is nested or not. It has no impact at all on how the problem is solved, nor does the name of the class. – Servy Oct 30 '18 at 18:21
  • @Servy So if I understand what you are saying, my suggestions will solve the problem, although not in a C#-idiomatic way. – Code-Apprentice Oct 30 '18 at 18:22
  • No, I'm saying your solution doesn't solve the problem at all, because the problem has nothing to do with whether the class is nested or not, or what it's name is. You have suggested a change that has no impact (positively or negatively) on the problem described. Thus it's not an answer to the question. – Servy Oct 30 '18 at 18:22
  • @Servy The exact problem isn't clearly stated in the OP. I assume that his attempt to translate the given Java into C# resulted in a compiler error. The changes I suggest should not have those same compiler errors. I fail to see how that doesn't solve the problem? – Code-Apprentice Oct 30 '18 at 18:24
  • Making the class not nested, or renaming it, will do nothing to remove the compiler errors they've mentioned. So no, it doesn't solve the problem stated. – Servy Oct 30 '18 at 18:27
  • As I stated before: "the implication behind my answer is that "static" would be removed." Which **will** solve the compiler errors. Of course, I probably should state this explicitly in my answer in addition to the multiple times I have stated it in the comments. – Code-Apprentice Oct 30 '18 at 18:29