C’è un modo per raggiungere un membro `protetto` di un altro object da un tipo derivato?

class MyBase { protected object PropertyOfBase { get; set; } } class MyType : MyBase { void MyMethod(MyBase parameter) { // I am looking for: object p = parameter.PropertyOfBase; // error CS1540: Cannot access protected member 'MyBase.PropertyOfBase' via a qualifier of type 'MyBase'; the qualifier must be of type 'MyType' (or derived from it) } } 

Esiste un modo per ottenere una proprietà protetta di un parametro di un tipo da un tipo di estensione senza riflessione? Dal momento che la class estesa conosce la proprietà attraverso il suo tipo di base, avrebbe senso se ansible.

No, non puoi farlo.

Sei autorizzato ad accedere a membri protetti di oggetti del tipo di accesso (o derivati ​​da esso). Qui, non sappiamo se il parametro è di tipo MyType o SomeOtherCompletelyDifferentType.

EDIT: il bit rilevante delle specifiche C # 3.0 è la sezione 3.5.3:

Quando si accede a un membro di un’istanza protetta al di fuori del testo del programma della class in cui è dichiarato e quando si accede a un membro di un’istanza interna protetta all’esterno del testo del programma in cui è dichiarato, l’accesso deve avvenire all’interno di una class dichiarazione che deriva dalla class in cui è dichiarata. Inoltre, l’accesso è necessario per passare attraverso un’istanza di quel tipo di class derivata o un tipo di class costruito da esso. Questa restrizione impedisce a una class derivata di accedere ai membri protetti di altre classi derivate, anche quando i membri sono ereditati dalla stessa class base.

L’ultima volta che ho affrontato un problema simile, ho usato la soluzione per aggiungere un metodo statico protetto alla base:

 class MyBase { protected object PropertyOfBase { get; set; } protected static object GetPropertyOfBaseOf(MyBase obj) { return obj.PropertyOfBase; } } class MyType : MyBase { void MyMethod(MyBase parameter) { object p = GetPropertyOfBaseOf(parameter); } } 

C’è una buona ragione per cui non puoi farlo. Supponiamo che qualcuno scriva:

 class Other : MyBase { } new MyType().MyMethod(new Other()); 

Se la lingua ha consentito ciò che stai chiedendo, potresti violare gli invarianti ipotizzati di Other modificando il valore di PropertyOfBase .

Penso che dovresti chiederti se esiste un modo migliore di fare ciò che vuoi fare. Si desidera che PropertyOfBase operi come pubblico nel contesto di MyType.MyMethod (), ma che sia protetto in tutte le altre situazioni. Perché?

Una proprietà protetta è accessibile solo a un’istanza di una class derivata, non a istanze di classi derivate.

C’è una differenza e ha senso, i membri protetti non dovrebbero rinunciare al loro valore per qualsiasi altra istanza, nemmeno un’istanza derivata dallo stesso tipo.

(Modificato, mi sono preso un po ‘di lingua legata!)

Poiché si eredita da MyBase, è ansible accedere a tutti i campi / proprietà / metodi da esso contrassegnati come “protetti” utilizzando la parola chiave “base”.

 public class MyBase { protected object PropertyOfBase { get; set; } } public class MyType : MyBase { void MyMethod() { object p = base.PropertyOfBase; } } 

Puoi anche dichiarare MyType come una class nidificata di MyBase (invece di ereditare), in questo modo puoi accedere ai membri privati ​​/ protetti quando invii la class MyBase come parametro

 public class MyBase { protected object PropertyOfBase { get; set; } public class MyType { public void MyMethod(MyBase parameter) { object p = parameter.PropertyOfBase; } } } 

Per creare un’istanza di MyType basta usare

 var t = new MyBase.MyType(); t.MyMethod(new MyBase());