Wenn Wenn Sie die Änderungsoperationen zum Zeitpunkt der Kompilierung sperren möchten, benötigen Sie eine typsichere Lösung.
Deklarieren Sie eine Schnittstelle für die öffentlich zulässigen Operationen. Verwenden Sie diese Schnittstelle als Eigenschaftstyp.
Dann deklarieren Sie eine Klasse, die diese Schnittstelle implementiert und von der Standardauflistungsklasse erbt.
public class SafeList<T> : List<T>, IReadOnlyList<T> { }
Vorausgesetzt, dass Sie die Schnittstellendefinition richtig, werden Sie nichts von Hand implementieren müssen, da die Basisklasse bereits die Implementierungen bietet.
Verwenden Sie diese abgeleitete Klasse als den Typ des Felds, in dem der Eigenschaftswert gespeichert wird.
public class A
{
private SafeList<string> _list = new SafeList<string>();
public IReadOnlyList<string>
{
get { return _list; }
}
}
Innerhalb der Klasse A können Sie _list
direkt verwenden und so den Inhalt ändern. Clients der Klasse A können nur die Untermenge von Operationen verwenden, die über IReadOnlyList<T>
verfügbar sind.
Für Ihr Beispiel verwenden Sie SortedList statt List, so wahrscheinlich die Schnittstelle
public interface IReadOnlyDictionary<K, V> : IEnumerable<KeyValuePair<K, V>>
{
V this[K index] { get; }
}
ich es IEnumerable auch erben gemacht habe sein muss, die nur lesbar ist sowieso, so ist vollkommen sicher . Die sichere Klasse wäre dann:
public class SafeSortedList<K, V> : SortedList<K, V>, IReadOnlyDictionary<K, V> { }
Aber sonst ist es die gleiche Idee.
Update: gerade bemerkt, dass (aus irgendeinem Grund kann ich nicht ergründen) Sie nicht modifizierende Operationen zu verbieten wollen - Sie wollen nur einige modifizierende Operationen zu verbieten. Sehr seltsam, aber es ist immer noch die selbe Lösung. Was auch immer Operationen, die Sie zulassen wollen, „öffnen sie nach oben“ in der Schnittstelle:
public interface IReadOnlyDictionary<K, V> : IEnumerable<KeyValuePair<K, V>>
{
V this[K index] { get; set; }
}
Natürlich, das ist der falsche Name für die Schnittstelle jetzt ... warum auf der Erde würden Sie wollen, über Add Hinzufügen verbieten, aber nicht verbieten es über den Indexer? (Der Indexer verwendet werden können Artikel hinzufügen, genauso wie die Add-Methode kann.)
aktualisieren
Von Ihrem Kommentar Ich glaube, Sie bedeuten, dass Sie Zuordnung auf den Wert eines vorhandenen Schlüssels zulassen möchten/Wertpaar, aber Zuweisung zu einem zuvor unbekannten Schlüssel nicht zulassen. Da Schlüssel zur Laufzeit durch Strings angegeben werden, gibt es keine Möglichkeit, das zur Kompilierungszeit zu erfassen. So man kann auch zur Laufzeitprüfung gehen:
public class FixedSizeDictionaryWrapper<TKey, TValue> : IDictionary<TKey, TValue>
{
IDictionary<TKey, TValue> _realDictionary;
public FixedSizeDictionaryWrapper(IDictionary<TKey, TValue> realDictionary)
{
_realDictionary = realDictionary;
}
public TValue this[TKey key]
{
get { return _realDictionary[key]; }
set
{
if (!_realDictionary.Contains(key))
throw new InvalidOperationException();
_realDictionary[key] = value;
}
}
// Implement Add so it always throws InvalidOperationException
// implement all other dictionary methods to forward onto _realDictionary
}
Jedes Mal, wenn ein gewöhnliches Wörterbuch haben, und Sie möchten ein bestimmtes Verfahren geben Sie es, dass Sie nicht vertrauen, die vorhandenen Werte zu aktualisieren, wickeln Sie es in einem der diese.
Bitte sagen Sie mir, dass Sie nicht No-Vowels-erlaubt Notation auf einer täglichen Basis verwenden! Ich nehme an, es war nur für dieses Beispiel. Ich beschäftige mich den ganzen Tag mit Notation bei der Arbeit, die ich "einen Vokal erlaubt, aber es ist nicht immer der erste!"; Es ist schrecklich zu lesen. – jcollum
Ja, einverstanden, aber es ist ein Freitag Nacht Post ... – Alex