How is Java's notion of static different from

2019-04-08 02:50发布

I am reading Josh Bloch's book Effective Java and he suggests using a builder design pattern when building objects that have large amounts of members. From what I can see it isn't the vanilla design pattern but looks like his variation. I rather like the look of it and was trying to use it in a C# web application that I am writting. This is the code written in Java and works perfectly

public class Property { 

    private String title;
    private String area;

    private int sleeps = 0;

    public static void main(String[] args) {

        Property newProperty = new Property.Builder("Test Property").Area("Test Area").Sleeps(7).build();

    }

    private Property(Builder builder) {
        this.title = builder.title;
        this.area = builder.area;
        this.sleeps =builder.sleeps;
    }

    public static class Builder{
        private String title;
        private String area;

        private int sleeps = 0;

        public Builder (String title){
            this.title = title;
        }

        public Builder Area(String area){
            this.area = area;
            return this;
        }

        public Builder Sleeps(int sleeps){
            this.sleeps = sleeps;
            return this;
        }

        public Property build() {
            return new Property(this);
        }
    }   
}

When I put this into what I think is the C# equivalent

 public class Property
    {
    private String title;
    private String area;

    private Property(Builder Builder)
    {
        title = Builder.title;
        area = Builder.area;
    }


    public static class Builder
    {
        // Required parameters
        private String title;
        private String area;

        // Optional parameters
        private int sleeps = 0;

        public Builder(String val)
        {
            this.title = val;
        }

        public Builder Area(String val)
        {
            this.area = val;
            return this;
        }

        public Builder Sleeps(int val)
        {
            this.sleeps = val;
            return this;
        }

        public Property build()
        {
            return new Property(this);
        }
    }
    }

Then I get compiler warnings. Most of them "cannot declare instance members in a static class".

So my question is firstly what have I missed? If I have missed something, can I do it in the manner Josh Bloch recommends but in C#, and lastly, and this one important too, is this thread-safe?

标签: c# java static
9条回答
SAY GOODBYE
2楼-- · 2019-04-08 03:41

To answer several comments about how to get Java's inner class behavior in C#, it would seem that the reference to the enclosing class needs to be passed in the constructor of the inner class (from a quick Google - C# may have since added the capability).

public class Outer 
{

...
void SomeMethod() {
    Inner             workerBee=new Inner(this);
    }
...

    class Inner
    private Outer outer;
    {
    Inner(Outer out) {
        outer=out;
        }
    }
}

So C# just makes explicit what Java did implicitly, including explicitly needing the reference to access members of the outer class.

Personally, I have never liked the Java implicit accesses to the outer classes members, since it seems too easy to trip up and accidently break encapsulation - I nearly always create my inner classes as static and pass them a reference to the outer class.

查看更多
贼婆χ
3楼-- · 2019-04-08 03:43

Assuming that your class has publicly settable properties corresponding to the builder members, you don't need Bloch's builder pattern in C#. You can use Object Initializers:

public class Property 
{ 

    public String Title {get; set};
    public String Area {get; set};
    public int Sleeps {get; set};

    public static void main(String[] args)
    {

        Property newProperty = new Property {Title="Test Property", Area="Test Area", Sleeps=7};

    }
}

This won't be possible if you need more encapsulation.

查看更多
Rolldiameter
4楼-- · 2019-04-08 03:52

I will try removing the static keyword. My other thought was, as others have already suggested, was to create the builder class as a top level class.

查看更多
登录 后发表回答