2009-02-15 12 views
6

IRC için bir sunucu bağlantısına sahip bir sınıf Server var. Bilinen User s listesini içerir ve bunları gerektiği gibi oluşturur.Diğer kullanıcılara gizlenmiş bir sınıf için görünür yöntemleri/özellikleri oluşturma

  1. Herkes User bir örneğini oluşturabilir:

    Ben User sınıfına dahil iki sorun var. Bunu yapabilmek için sadece Server sınıfını istiyorum.

  2. Bir kullanıcı (User adlı öğeyi açıklar) kendi adını (veya birleştirilmiş kanallar gibi diğer bilgileri) değiştirirse, Server sınıfı kendisini değiştirebilir. Ancak, diğer sınıflar da yapabilir! Diğer sınıflara bu bilgiye dokunmaktan vazgeçmek istiyorum (bunu sadece onlara okuyarak).

Bu iki sorunu nasıl çözebilirim? C++ 'da, friend anahtar sözcüğünü kullanarak ve ctor ve setName (ve benzeri) özel kullanarak çözülebilir.

Belirli bir yöntemin belirli bir sınıf tarafından erişilebilir olmasını sağlayan bir C# anahtar sözcüğü var mı? Bu benim problemimi çözecek.

cevap

8

C++ 'dan kaynaklanan hatalı tasarımın semptomatik olması için friend erişimini dürüstçe buluyorum. Tasarımını düzeltmek daha iyi.

Bir kullanıcı, bir Kullanıcı bir kullanıcı oluşturduğunda gerçekten kimin umrundadır? Gerçekten önemli mi? Bunu soruyorum çünkü bazen programcılar sadece gerçekleşmeyecek şeyler hakkında endişeleniyorlar ya da eğer yaparlarsa önemli değiller.

Gerçekten umurunda yoksa aşağıdakilerden birini yapın:

  • Yap Kullanıcı bir arayüz. Sunucu, bunu uygulayan özel bir sınıfı başlatabilir; veya Kullanıcı bir iç yapıcı içermeyen bir iç sınıf sınıfı yapın, böylece yalnızca Sunucu bunu oluşturabilir.

Görünürlük (C++'daki arkadaşlardan biri olan ve Java'daki paket erişiminin iyi örnekleri olduğu) görünür kesmeler, yalnızca sorun değil, iyi bir fikirdir.

+0

Önerdiğiniz iki yöntemle gittim. Bir arabirim IUser ve bir ServerUser iç sınıfı oluşturdum. (Ayrıca, Sunucuları iki sınıfa bölerim, böylece diğerleri kendi özel IRC istemcilerini yazabilirler.) Cevabınız için teşekkürler! – strager

5

.NET dünyasında friend'a en yakın olan internal görünürlüğüdür.

İki sınıfınız ayrı montajlarda ise, diğer iç içe geçmişlerin bir montaj görünürlüğüne izin vermek için InternalsVisibleTo özniteliğini kullanabilirsiniz.

1

Sınıf hiyerarşinizin yeniden tasarlanması, muhtemelen bu sorun için adil bir çözümdür. Çünkü bana gerçekten ihtiyacınız olan şey gibi geliyor çünkü Sunucu sınıfı dışında mevcut olduğunda salt okunur bir Kullanıcı sınıfı.

// An abstract base class. This is what I'd use outside the 
// Server class. It's abstract, so it can't be instantiated 
// on its own, and it only has getters for the properties. 
public abstract class User 
{ 
    protected User() 
    { 
    } 

    public string Name { get;} 
    // Other get-only properties 
} 

public class ServerUser : User 
{ 
    public ServerUser() 
    { 
    } 

    public string Name { get; set;} 
    // Other properties. 
} 

Ardından Sunucu sınıfı yarattı ServerUser sınıfları, kullanıcı için kullanıcı sınıfları (kullanıcı adı değiştirme gibi) ServerUser sınıfları üzerinde özelliklerini değiştirmek sadece açığa Sunucu sınıfı:

muhtemelen böyle bir şey yapacağını dış dünya.