我有一个内部类,内部构造函数不允许在通用集合中使用它,因此我将其更改为public。如果在内部类中有公共构造函数,那么可访问性是什么?与内部构造函数有什么不同?
答案 0 :(得分:47)
两者基本相同。我看到的区分它们的一个论点是,使构造函数internal
确保类型只会被当前程序集中的类型实例化,即使后来确定类型本身应该是{{1而不是public
。换句话说,您可以决定更改类型的可见性,而不会解除对其实例化的限制。
使构造函数internal
具有相反的效果(显然),如果您希望它可以在可见的任何地方实例化该类型,那么可能是明智的。
另外,正如您已经指出的那样,一个 small 的区别在于,如果构造函数的public
,该类型不能用作泛型类型的泛型类型参数internal
约束,因为此约束要求构造函数为where T : new()
。
答案 1 :(得分:12)
如果从公共函数返回该类的对象,则外部代码仍然可以使用具有内部构造函数的公共类。
然后外部代码可以访问该对象,但仍然无法创建新对象。
Assembly 1:
public class Exclusive
{
internal Exclusive() {}
public void DoSomething() {}
}
public class Factory
{
public Exclusive GetExclusive() { return new Exclusive(); }
}
Assembly 2:
Factory MyFactory = new Factory();
Exclusive MyExclusive = MyFactory.GetExclusive(); // Object is created in Assembly 1
MyExclusive.DoSomething();
Exclusive MyExclusive = new Exclusive(); // Error: constructor is internal
而内部类根本不能在程序集外部使用:
Assembly 1:
internal class Exclusive
{
public Exclusive() {}
public void DoSomething() {}
}
public class Factory
{
public Exclusive GetExclusive() { return new Exclusive(); }
}
Assembly 2:
Factory MyFactory = new Factory();
Exclusive MyExclusive = MyFactory.GetExclusive(); // Error: class Exclusive not found
答案 2 :(得分:4)
将内部或公共构造函数设置为内部类型在可见性方面是等效的。
答案 3 :(得分:2)
内部构造函数很好。如果要控制实例的创建方式,通常需要执行此操作。您必须提供Factory以在同一程序集中的另一个类中生成类以在内部生成实例,然后作为属性公开
答案 4 :(得分:0)
另一个重要区别是,要使用反射访问internal
构造函数,您需要在调用Type.GetConstructor()
时指定绑定标志 - Type.GetConstructor(Type[])
重载只返回公共构造函数:
using System;
internal class WithPublic
{
public WithPublic() { }
}
internal class WithInternal
{
internal WithInternal() { }
}
public class Program
{
public static void Main()
{
Console.WriteLine(typeof(WithPublic).GetConstructor(new Type[] { }) == null); //false
Console.WriteLine(typeof(WithInternal).GetConstructor(new Type[] { }) == null); //true
}
}
当您使用利用Type.GetConstructor(Type[])
重载的库(例如Microsoft Unity)时,这可能很重要。