2012-10-19 24 views
5

Konteyner sınıfı ve dış sınıflar için erişilebilir olan iç içe geçmiş bir sınıf tanımlamak istiyorum, ancak iç içe geçmiş sınıfın örneklenmesini denetlemek istiyorum, yalnızca kapsayıcı sınıfın örnekleri, iç içe geçmiş sınıfın yeni örneklerini oluşturabilir.Dış sınıflar tarafından iç içe geçmiş bir sınıfın erişime izin vermesine izin ver ancak izin verilsin

geçmeden kodu umarım bu göstermelidir: Bu External tarafından erişilebilir olması için

public class Container 
{ 
    public class Nested 
    { 
     public Nested() { } 
    } 

    public Nested CreateNested() 
    { 
     return new Nested(); // Allow 
    } 
} 

class External 
{ 
    static void Main(string[] args) 
    { 
     Container containerObj = new Container(); 
     Container.Nested nestedObj; 

     nestedObj = new Container.Nested();  // Prevent 
     nestedObj = containerObj.CreateNested(); // Allow 

    } 
} 

Nested genel olması gerekir. Nested için yapıcıyı oluşturmayı denedim, ancak Container, Container'un Nested temel bir sınıfı olmadığından örneklerin oluşturulmasını engeller. Nested için kurucuyu internal olarak ayarlayabilirim, ancak kurucuya aynı montajdakiler de dahil olmak üzere tüm harici sınıflar tarafından erişimi engellemek istiyorum. Bunu yapmanın bir yolu var mı?

Bu, erişim değiştiricileri aracılığıyla gerçekleştirilemiyorsa, Nested() içinde bir istisna atabilmem mümkün olabilir. Bununla birlikte, new Nested()'un çağrıldığı bağlamı nasıl test edeceğimi bilmiyorum.

cevap

6

Bir arabirim aracılığıyla soyutlama hakkında ne dersiniz?

public class Container 
{ 
    public interface INested 
    { 
     /* members here */ 
    } 
    private class Nested : INested 
    { 
     public Nested() { } 
    } 

    public INested CreateNested() 
    { 
     return new Nested(); // Allow 
    } 
} 

class External 
{ 
    static void Main(string[] args) 
    { 
     Container containerObj = new Container(); 
     Container.INested nestedObj; 

     nestedObj = new Container.Nested();  // Prevent 
     nestedObj = containerObj.CreateNested(); // Allow 

    } 
} 

Ayrıca soyut bir taban sınıfı ile aynı şeyi yapabilirsiniz:

public class Container 
{ 
    public abstract class Nested { } 
    private class NestedImpl : Nested { } 
    public Nested CreateNested() 
    { 
     return new NestedImpl(); // Allow 
    } 
} 

class External 
{ 
    static void Main(string[] args) 
    { 
     Container containerObj = new Container(); 
     Container.Nested nestedObj; 

     nestedObj = new Container.Nested();  // Prevent 
     nestedObj = containerObj.CreateNested(); // Allow 

    } 
} 
+0

Çalışıyor! Teşekkürler! –

1

Böyle bir şekilde sınıf bildirmek mümkün değildir. Bunun sizin için en iyi yolun özel olarak sınıf olarak ilan edilmesini ve herkese açık arabirim aracılığıyla açığa çıkarıldığını düşünüyorum:

class Program 
{ 
    static void Main(string[] args) 
    { 
     // new S.N(); does not work 
     var n = new S().Create(); 
    } 
} 

class S 
{ 
    public interface IN 
    { 
     int MyProperty { get; set; } 
    } 
    class N : IN 
    { 
     public int MyProperty { get; set; } 
     public N() 
     { 

     } 
    } 

    public IN Create() 
    { 
     return new N(); 
    } 
} 
İlgili konular