34
votes

I have the folowing class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Odbc;

namespace Framework
{
    public class OracleProvider
    {
        private OdbcConnection db { get; private set; }
        private String dbUsername = Settings.Default.Username;
        private String dbPassword = Settings.Default.Password;

        public OracleProvider()
        {
            connect();
        }

        public void connect()
        { 
            db = new OdbcConnection("Driver={Microsoft ODBC for Oracle};Server=CTIR; UID="+dbUsername+";PWD="+dbPassword+";");    
        }        
    }
}

Now I get the following error:

Error 11: The accessibility modifier of the 'Framework.OracleProvider.db.set' accessor must be more restrictive than the property or indexer 'Framework.OracleProvider.db'

I've been looking at similar questions but haven't really found an answer.

Can anyone explain to me why this is happening? I really want to learn.

2

2 Answers

52
votes

This is the problem:

private OdbcConnection db { get; private set; }

Assuming you really want both the getter and setter to be private, this should be:

private OdbcConnection db { get; set; }

The setter is already private, as that's the accessibility of the overall property.

Alternatively, if you want the getter to be non-private and the setter to be private, you need to specify some other modifier, e.g.

internal OdbcConnection db { get; set; }

Basically, if you're going to specify an access modifier on the get; or set; part of a property, it has to be more restrictive than it would otherwise be.

From section 10.7.2 of the C# specification:

The accessor-modifier must declare an accessibility that is strictly more restrictive than the declared accessibility of the property or indexer itself. To be precise:

  • If the property or indexer has a declared accessibility of public, the accessor-modifier may be either protected internal, internal, protected, or private.
  • If the property or indexer has a declared accessibility of protected internal, the accessor-modifier may be either internal, protected, or private.
  • If the property or indexer has a declared accessibility of internal or protected, the accessor-modifier must be private.
  • If the property or indexer has a declared accessibility of private, no accessor-modifier may be used.

(As an aside, if it's private for both reading and writing, it would probably be better just to use a field. Most of the benefits of using a property are only present if it's exposed beyond the current class. And if you do keep it as a property, consider renaming it to follow normal .NET naming conventions.)

7
votes

Well, the error tells all the information required:

accessibility modifier ... accessor must be more restrictive than the property ...

  private OdbcConnection db { // <- property as whole is "private"
    get; 
    private set; // <- accessor (set) is explictly declared as "private" 
  }

So you can do either

  // property as a whole is "public", but "set" accessor is "private"
  // and so the accessor is more restrictive than the property
  public OdbcConnection db { // <- property as whole is "public"
    get; 
    private set; // <- accessor is "private" (more restrictive than "public")
  }

Or

  private OdbcConnection db { 
    get; 
    set; // <- just don't declare accessor modifier
  }