La soluzione che ho trovato per impedire l'ereditarietà cross-assembly ha profumo di pattern:
Come fare sì che la classe pubblica FooBase sia ereditabile esclusivamente all'interno di FooIn (l'assembly che la contiene) ma istanziabile anche all'esterno di questo?
// FooIn.cs
// csc /t:library FooIn.cs
using System;
public class FooBase
{
internal FooBase(){}
public static FooBase CreateFooBase()
{
return new FooBase();
}
public void DoSomething()
{
Console.WriteLine("FooBase");
}
}
// OK
public class FooInside: FooBase
{
public void DoSomethingElse()
{
Console.WriteLine("FooInside");
}
}
Quindi riusciamo a derivare FooInside da FooBase (perché si trovano tutte e due in FooIn.dll) ma non è possibile derivare FooOutside da FooBase (perché si trova in un altro assembly, FooOut.dll):
// FooOut.cs
// csc /t:library /r:FooIn.dll FooOut.cs
// error CS0122:
// 'FooBase.FooBase()' is inaccessible due to its protection level
public class FooOutside: FooBase
{
//...
}
Curioso di vedere che altre classi all'interno del Framework .NET seguino questo pattern, ne ho scoperta una: System.Reflection.Assembly. E' giusto impedire l'ereditarietà da questa classe però, non al costo di sealed (System.Reflection.Emit.AssemblyBuilder deve derivare da essa).
Feedback? Idee per un nome?