Jak wspomniano przez scrwtp, this
wydaje się być powszechnie używanym identyfikatorem i jest to moje preferencje. Innym bardzo powszechnym jest x
. Zwykle używam identyfikatora na poziomie klasy, gdy jest on używany wielokrotnie w klasie i oczywiście, gdy jest używany w konstruktorze. I w tych przypadkach użyłbym __
(dwa podkreślenia) jako identyfikator poziomu elementu, aby zaznaczyć, że wartość jest ignorowana. Nie można użyć numeru _
i zignorować go, ponieważ jest to błąd kompilacji, ale narzędzia do linkowania często będą uważać, że to __
, i uniknąć ostrzeżenia o nieużywanym identyfikatorze.
Po dodaniu identyfikatora poziomu klasy i nie używać go można dostać ostrzeżenie:
Rekurencyjne obiekt odniesienia „ja” jest nieużywany. Obecność referencji obiektu rekursywnego dodaje kontrole inicjowania w czasie wykonywania do elementów w tym i wyprowadzonych typach. Rozważ usunięcie tego rekurencyjnego odwołania do obiektu.
Rozważmy następujący kod:
type MyClass() =
member self.X = self
type MyClassAsSelf() as self =
member __.X = self
type MyClassAsSelfUnused() as self = // <-- warning here
member __.X =()
To właśnie te zajęcia wyglądają jak po kompilacji/dekompilacji:
public class MyClass
{
public Program.MyClass X
{
get
{
return this;
}
}
public MyClass() : this()
{
}
}
public class MyClassAsSelf
{
internal FSharpRef<Program.MyClassAsSelf> self = new FSharpRef<Program.MyClassAsSelf>(null);
internal int [email protected];
public Program.MyClassAsSelf X
{
get
{
if ([email protected] < 1)
{
LanguagePrimitives.IntrinsicFunctions.FailInit();
}
return LanguagePrimitives.IntrinsicFunctions.CheckThis<Program.MyClassAsSelf>(this.self.contents);
}
}
public MyClassAsSelf()
{
FSharpRef<Program.MyClassAsSelf> self = this.self;
this..ctor();
this.self.contents = this;
[email protected] = 1;
}
}
public class MyClassAsSelfUnused
{
internal int [email protected];
public Unit X
{
get
{
if ([email protected] < 1)
{
LanguagePrimitives.IntrinsicFunctions.FailInit();
}
}
}
public MyClassAsSelfUnused()
{
FSharpRef<Program.MyClassAsSelfUnused> self = new FSharpRef<Program.MyClassAsSelfUnused>(null);
FSharpRef<Program.MyClassAsSelfUnused> self2 = self2;
this..ctor();
self.contents = this;
[email protected] = 1;
}
}
Należy zauważyć, że istnieje kontrola, czy zmienna została ustawiona w konstruktorze. Jeśli kontrola nie powiedzie się, wywoływana jest funkcja: LanguagePrimitives.IntrinsicFunctions.FailInit()
.Jest to wyjątek zgłoszony:
System.InvalidOperationException: Inicjalizacja obiektu lub wartości spowodowała, że obiekt lub wartość były dostępne rekursywnie przed całkowitym zainicjowaniem.
Domyślam się, że ostrzeżenie jest po to, aby uniknąć lekkiego niepotrzebnego czeku. Jednak nie wiem, jak skonstruować sytuację, w której błąd jest generowany, więc nie znam dokładnego celu tej kontroli. Być może ktoś inny może rzucić światło na to?
Jest to istotne, gdy dziedziczenie pojawia się w obrazie - pamiętam, że widziałem to w wyjątkowo owłosionym scenariuszu z podstawową klasą abstrakcyjną z własnym identyfikatorem. Ale nie mam tu żadnego przytoczonego z zewnątrz, samodzielnego przykładu. – scrwtp