How to restrict access to nested class member to enclosing class?

Viewed 24943

Is it possible to specify that members of a nested class can be accessed by the enclosing class, but not other classes ?

Here's an illustration of the problem (of course my actual code is a bit more complex...) :

public class Journal
{
    public class JournalEntry
    {
        public JournalEntry(object value)
        {
            this.Timestamp = DateTime.Now;
            this.Value = value;
        }

        public DateTime Timestamp { get; private set; }
        public object Value { get; private set; }
    }

    // ...
}

I would like to prevent client code from creating instances of JournalEntry, but Journal must be able to create them. If I make the constructor public, anyone can create instances... but if I make it private, Journal won't be able to !

Note that the JournalEntry class must be public, because I want to be able to expose existing entries to client code.

Any suggestion would be appreciated !


UPDATE: Thanks everyone for your input, I eventually went for the public IJournalEntry interface, implemented by a private JournalEntry class (despite the last requirement in my question...)

7 Answers

The solution Grizzly suggested does make it a bit hard to create the nested class somewhere else but not impossible,like Tim Pohlmann wrote someone can still inherit it and use the inheriting class ctor.

I'm taking advantage of the fact that nested class can access the container private properties, so the container asks nicely and the nested class gives access to the ctor.

 public class AllowedToEmailFunc
{
    private static Func<long, EmailPermit> CreatePermit;

    public class EmailPermit
    {
        public static void AllowIssuingPermits()
        {
            IssuegPermit = (long userId) =>
            {
                return new EmailPermit(userId);
            };
        }

        public readonly long UserId;

        private EmailPermit(long userId) 
        {
            UserId = userId;
        }
    }

    static AllowedToEmailFunc()
    {
        EmailPermit.AllowIssuingPermits();
    }

    public static bool AllowedToEmail(UserAndConf user)
    {
        var canEmail = true; /// code checking if we can email the user
        if (canEmail)
        {
            return IssuegPermit(user.UserId);
        }
        else
        {
            return null
        }

    }
}

This solution is not something I would do on a regular day on the job, not because it will lead to problems in other places but because it's unconventional (I've never seen it before) so it might cause other developers pain .

Related