2010-08-17 3 views
4

Рассмотрим в AssemblyOneНаследование класса и вызвать скрытый базовый конструктор

public class A 
{ 
    internal A (string s) 
    { } 
} 

public class B : A 
{ 
    internal B (string s) : base(s) 
    { } 
} 

В AssemblyTwo

public class C : B 
{ 
    // Can't do this - ctor in B is inaccessible 
    public C (string s) : base(s) 
} 

Очевидно, это код запах, но независимо от того, если быть плохой идеей возможно назвать ctor B от ctor C без изменения AssemblyOne?

ответ

5

Игнорировать сборку Два на данный момент. Вы не смогли бы создать экземпляр класса C, потому что он наследует от B, для которого нет общих конструкторов.

Итак, если вы удалите проблему наследования из класса C, у вас все еще будет проблема с созданием экземпляров класса B вне сборки B из-за уровней защиты. Однако вы могли бы использовать отражение для создания экземпляров B.

Для целей тестирования, я изменил свои классы следующим образом:

public class A 
{ 
    internal A(string s) 
    { 
     PropSetByConstructor = s; 
    } 

    public string PropSetByConstructor { get; set; } 
} 

public class B : A 
{ 
    internal B(string s) 
     : base(s) 
    { 
     PropSetByConstructor = "Set by B:" + s; 
    } 
} 

Я тогда написал консольное приложение для тестирования:

static void Main(string[] args) 
    { 
     System.Reflection.ConstructorInfo ci = typeof(B).GetConstructors(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)[0]; 
     B B_Object = (B)ci.Invoke(new object[]{"is reflection evil?"}); 

     Console.WriteLine(B_Object.PropSetByConstructor); 


     Console.ReadLine(); 
    } 

Я бы не рекомендовал делать это, его просто плохо практика. Я полагаю, что во всех случаях есть исключения, и исключение здесь, возможно, связано с сторонней библиотекой, которую вы не можете продлить. Это даст вам возможность создавать и отлаживать, если не наследовать.

2

Это невозможно, даже с отражением.

Если класс не имеет доступных конструкторов, нет способа создать класс, который наследует его.

1

Нет, вы должны изменить AssemblyOne.