views:

268

answers:

4

Example:

public class Name {

    public string FirstName { get; private set; }
    public string LastName { get; private set; }

    private Name() { }

    public Name(string firstName, string lastName) {

        FirstName = firstName;
        LastName = lastName;

    }  
}

When trying to instantiate this c# class, intellisense shows both the private and the public constructor for new keyword even though one of the constructor is private!

What is even more weird is that when I remove the second argument from the public constructor ( remove lastName as argument to public constructor), intellisense now shows just the public constructor with new keyword, correctly.

Is this a bug or am I missing something here? I am using VS2008 SP1.

edit: code clarity

+1  A: 

Wow, that's strange. I just tried it myself on my copy of VS2008 (I'm also running SP1) and had the exact same results. When there was more than one parameter, the private constructor showed up in Intellisense, but not when there was only one. My guess is, it's a bug.

BFree
Thanks for confirming my observation. Thought I was the only one!
Mank
A: 

Don't know why intellisense is showing you weird things. But you should have an abstract base class for you domain objects with a public constructor, so you don't have to pepper your objects with the private ones. You should also put there things like your properties for your primary keys and such.

public abstract class BaseDomainObject{
  public BaseDomainObject() { }

  private int _id;

  public virtual int Id { get { return _id; } set { _id = value; } }

}

public SomeDomainObject : BaseDomainObject{
  ...
}
Strelok
The Name is an immutable value object (DDD) for my domain classes. So does not really need an abstract base class.
Mank
A: 

It's likely a bug but not worth the effort to fix. Namely because there are numerous scenarios where accessing a private constructor is legal. Take the following snippet of code. All private constructor access is legal

class Outer {
  private Outer() {
  }
  public Outer Create() { return new Outer(); }
  class Inner() { 
    void Function1() { new Outer(); }
    class DoubleInner() {
       void Function2() { new Outer(); }
    }
  }
}
JaredPar
Yes, it is valid for inner classes but quite annoying for other API users to see an invalid constructor. Is there a better way to create an immutable object?
Mank
Don't define the private constructor at all. If you define an explicit constructor, no implicit constructor will be generated and hence accessibility won't be an issue. This only applies to reference types, value types will always have a default constructor
JaredPar
A: 

Even though the private constructor shows up in Intellisense the Compiler will still through an "inaccessible due to protection level" error if you try to compile code that uses it where it's not permitted

RobV