Propriété en lecture seule signifie que tu ne peux affecter de valeur à la propriété. Cela ne veut pas dire que l'objet est en lecture seule.
Tu ne peux donc pas faire
monObjet.MaPropriete = valeur;
Mais rien n'empêche de faire
monObjet.MaPropriete.Clear();
Pour ton problème tu peux, par exemple, renvoyer un copie en profondeur du dictionnaire (cf. méthode Clone, interface ICloneable). Résultat, même si l'utilisateur modifie le dictionnaire que tu lui renvoies, ton dictionnaire interne ne sera pas modifié.
A ce moment, plutôt que d'utiliser une propriété il vaut mieux utiliser une méthode pour obtenir ce dictionnaire. Une propriété est supposée être "rapide" d'accès, si le traitement est plus lourd il vaut mieux mettre une méthode (cf. ce lien pour un exemple similaire).
Sinon il faut comme l'indique Pol63 que tu fasses un wrapper autour du dictionnaire pour empêcher les modifications directes. Un peu comme les ReadOnlyCollection<T> de .Net.
Seul problème éventuellement, il sera toujours possible d'accéder aux valeurs et de les modifier
monDico[key].MaPropriete = valeur;
Si tu ne veux pas que ce soit possible, passe par une copie en profondeur. Ainsi même si l'utilisateur modifie l'élément, ta copie interne sera préservée.
Partager