views:

212

answers:

2

Why can NHibernate create a proxy for classes with properties that have private setters but not for classes with properties that have internal setters? Or am I missing something that should be completely obvious?

public class PrivateSetter {
    // no proxy error
    public virtual string PrivateSetterProperty { get; private set; }
}

public class InternalSetter {
    // proxy error
    public virtual string InternalSetterProperty { get; internal set; }
}
+1  A: 

You need to mark the setter as protected internal so that the proxy class can access it:

public class InternalSetter 
{
    public virtual string InternalSetterProperty { get; protected internal set; }
}
Jamie Ide
http://msdn.microsoft.com/en-us/library/ba0a1yw2%28VS.80%29.aspx talks about the difference between internal and protected internal. protected internal is actually protected OR internal. @Jamie, can we use the InternalsVisibleTo attribute to make Nhibernate or the CastleProxy see the internal setter?
Amith George
I know about protected internal. My question is about how the proxy class accesses private setters but not internal setters.Is there something weird with reflection in a full-trust environment where you can see private stuff but not internal stuff?
kuhlmancer
Internal members are not recognized in Reflection, see http://stackoverflow.com/questions/171332/accessing-internal-members-via-system-reflection. I haven't tried InternalsVisibleTo, once I found that protected internal worked I didn't give it a second though.
Jamie Ide
A: 

This is a pure .NET language problem. Try it yourself:

public class A
{
    public virtual string PrivateSetter { get; private set; }
    public virtual string InternalSetter { get; internal set; }
}

in another assembly:

public class B : A
{
    // works fine, private isn't derived at all
    // you can omit the setter, make it public, internal to this 
    // assembly etc.
    public override string PrivateSetter { get; set; }

    // compilation time error: setter can't be overridden,
    // there is no access to it.
    public override string InternalSetter { get; internal set; }
}

By the way, I'm just analyzing an issue with private setters and proxies, so I'm not sure if the proxies really work in this case.

Stefan Steinegger