F # 3.0 aggiunge controlli più rigidi per le chiamate ai membri base
e protected
. Ho qualcosa come la seguente classe astratta in C# che ha metodi di supporto protected static
da utilizzare per le classi derivate.Informazioni sulla modifica dell'utilizzo dei membri protetti/di base in F # 3.0
public abstract class Processor {
public abstract void Process();
protected static void Helper(object arg) { }
}
in F #, uno di quei metodi di supporto è passato come una funzione di prima classe:
type DerivedProcessor() =
inherit Processor()
let init f =
f()
override x.Process() =
init Processor.Helper
compila senza lamentarsi in 2.0, ma in 3,0 produce un errore:
A protected member is called or 'base' is being used. This is only allowed in the direct implementation of members since they could escape their object scope.
OK, è abbastanza facile da rispettare, basta avvolgere la chiamata in un altro membro statico
static member private HelperWrapper(arg) = Processor.Helper(arg)
e passare quello intead. Ma perché?
C# non ha alcun problema con questo stesso modello.
public class HappyToCompile : Processor {
private void Init(Action<object> f) {
f(null);
}
public override void Process() {
Init(Helper);
}
}
Le domande:
- Perché sono stati aggiunti i controlli più severi?
- (e relativo) Quale terribile problema risolve una soluzione così banale?
- C'è un design migliore che questo dovrebbe incoraggiare?
Hai risposto alla prima domanda e il blog di Eric risponde alla seconda. È facile sorvolare le differenze tra 'Func <_>' e 'FSharpFunc <_>'. In che modo è stato possibile refactoring per eliminare 'protected'? – Daniel
Bene, perché è protetto in primo luogo? Se vuoi che sia accessibile solo alle sottoclassi, allora non c'è molto che tu possa fare. Forse potresti esporre 'Helper' come una proprietà protetta di tipo 'Action
Questa sarebbe una buona aggiunta a [_Breaking Changes_] (http://msdn.microsoft.com/en-us/library/hh416791). Un'altra [domanda recente] (http://stackoverflow.com/q/11978234/162396) potrebbe essere un buon candidato. – Daniel