| 

.NET C# Java Javascript Exception

3
Hallo zusammen ...

Kann ich eine Property, die über ein Interface über ein public set verfügt in der konkreten Implementierung irgendwie readonly machen?

Ich bin über folgendes gestolpert:

ISignal
{
string Dummy { get; set; }
}


Signal : ISignal
{
public Dummy
{
get { return dummy; }
set { throw new Exception("Not allowed");
}
}


Das finde ich natürlich sehr unschön, weil mir während der Implementierung vorgegaukelt wird, dass eine Zuweisung funktioniert, es aber zur Laufzeit kracht. Deswegen würde ich gerne den Setter irgendwie readonly machen. Geht das nachträglich?
16.05.2013
cobject 13 4
2 Antworten
3
Nein, das geht nicht, und es wäre auch nicht sinnvoll, denn normalerweise wird der Nutzer Deiner Klasse gegen das Interface programmieren. Er hat also nur eine Variable vom Typ ISignal im Zugriff (der er am Anfang vielleicht eine Instanz von Signal zuweist). Damit kann er den Setter auf jeden Fall aufrufen, selbst wenn Du den Setter in Signal "abklemmst". Ein Interface ist ein Vertrag, der beim Implementieren einzuhalten ist. Wenn der Vertrag einen Setter vorsieht, mußt Du ihn implementieren.

Das Beispiel, über das Du gestolpert bist, ist tatsächlich nicht schön, aber im Prinzip nicht so unüblich. Es gibt sogar ein paar Framework-Klassen, die so funktionieren. Allerdings werfen die dann eine NotSupportedException, keine "generelle" Exception (was man im übrigen sowieso vermeiden sollte), und sie bieten meist eine Eigenschaft (z.B. "IsWritable"), über die man abfragen kann, ob der Setter unterstützt wird oder nicht.
16.05.2013
Matthias Hlawatsch 13,2k 4 9
1
Du kannst den "set"-Teil im Interface weglassen. Dann kommt eine Compilerfehlermeldung wenn du versuchst schreibend darauf zuzugreifen. "Einer Eigenschaft oder einem Indexer "Signal.Dummy" kann nichts zugewiesen werden -- sie sind schreibgeschützt."

interface ISignal
{
string Dummy { get; }
}

public class Signal : ISignal
{
private string dummy = "DefaultValue";

public string Dummy
{
get { return dummy; }
}
}


Du wirst nicht daran gehindert trotzdem einen Setter zu implementieren. Diesen kannst du mit entsprechenden Zugriffsmodifiern ausstatten so das du den Setter nur innerhalb deiner Klassen verwenden kannst (z.B.).

interface ISignal
{
string Dummy { get; }
}

public class Signal : ISignal
{
private string dummy = "DefaultValue";

public string Dummy
{
get { return dummy; }
private set { dummy = value; }
}
}


Jetzt würde beim Versuch schreibend auf Dummy zuzugreifen der Compiler folgenden Fehlermeldung werfen: "Die Eigenschaft oder der Indexer "Signal.Dummy" kann in diesem Kontext nicht verwendet werden, da der set-Accessor nicht verfügbar ist."
16.05.2013
Floyd 14,6k 3 9
Floyd 14,6k 3 9
OK, hier fehlte die Info, dass ich das Interface nicht ändern darf, da es an anderer Stelle auch benutzt wird.
cobject 16.05.2013

Stelle deine Interface-Frage jetzt!