Reputation: 31630
I was having the problem of wanting a property to have an internal getter and a protected setter, as described in this question, and I thought I solved that by doing the following:
public class Accessor : AccessorBase
{
private Connection _connection;
protected void setConnection(Connection value)
{
_connection = value;
}
internal Connection GetConnection()
{
return _connection;
}
...
}
However, I'm now getting this error:
Inconsistent accessibility: parameter type 'Connection' is less accessible than method 'setConnection(Connection)'
This is because I have internal class Connection
. I would rather not make Connection
a public class, while Accessor
needs to be public, so how can I get around this error while still maintaining an internal getter and a protected setter?
Upvotes: 8
Views: 6248
Reputation: 5414
Unfortunately C# doesn't support "internal and protected" access modifiers (only "internal or protected" is supported), which means any protected
members are visible outside the assembly and can't use an internal type.
Using internal
instead of protected
would be the most logical solution.
And you could vote at Microsoft Connect so that it might be added to C# someday.
Update: as of C# 7.2 you can use private protected
for this.
Upvotes: 10
Reputation: 56391
Create a public interface IConnection
that your internal Connection
object implements. Have your GetConnection
and SetConnection
methods accept and return IConnection
instead of Connection
.
Basic SOLID principles win again.
Upvotes: 5
Reputation: 31630
...any protected members are visible outside the assembly and can't use an internal type.
One way of getting around this is to make Connection
public while making all its instance methods and constructors internal.
Upvotes: 2
Reputation: 16065
Coincoin is correct, Accessor
is a public class anyone can derive from it, this means from a different assembly as well. That derived class now has protected method to which you need to pass an internal (from another assembly) class. This would never work.
You need to either make Accessor
internal or Connection
public, or better yet follow Randolphos answer
Here is a code example of the problem
Assembly 1
//this class is only visible in Assembly 1
internal class Connection
{
}
public class Accessor
{
protected void SetConnection(Connection con) { }
}
Assembly 2 - has reference to Assembly 1
//possible because Accessor is public
DerivedAccessor : Accessor
{
void SomeMethod()
{
this.SetConnection(????) // you can't pass Connection, its not visible to Assembly2
}
}
Upvotes: 0
Reputation: 27120
Unfourtanly you cannot do that. Since the Connection
is internal some class deriving from Accessor from another assembly would not be able to see Connection
, even if you mark the setter as protected internal
it would solve nothing.
Your only hope is to make the class Connection public.
Upvotes: 0
Reputation: 28596
If the class Connection is internal, a class deriving Accessor won't be able to call protected setConnection since it doesn't have access to Connection.
If setConnection is to be protected, Connection will have to be public.
Upvotes: 1
Reputation: 13672
Sorry, If you need that exact setup, you'll need to make your Connection
class public.
Upvotes: 0