具有泛型和“InternalsVisibleTo”的内部构造函数
Internal constructor with generics and `InternalsVisibleTo`
在使用 InternalsVisibleTo
属性时,是否可以使用带有内部无参数构造函数的 class 来与泛型一起使用?我知道您可以使用工厂方法或反射等...来执行此操作,但最好不要使用这些方法。
如果这不可能,这是设计使然吗?如果是,为什么?
取下面的代码:
Class图书馆
[assembly: InternalsVisibleTo("testapp")]
namespace Test
{
public class MyClass
{
internal MyClass()
{
}
}
}
申请
namespace Test
{
public class GenericClass<T> where T: new()
{
// Compiles fine due to the `InternalsVisibleTo` attribute
MyClass c = new MyClass();
T t = new T();
}
public class ConsumerClass
{
// gives the error: 'MyClass' must be a non-abstract type with a public
// parameterless constructor in order to use it as parameter 'T' in the
// generic type or method 'GenericClass<T>'
GenericClass<MyClass> g;
}
}
这是设计使然。来自 the spec,第 4.4.4 节:
If the constraint is the constructor constraint new()
, the type A must not be abstract and must have a public parameterless constructor. This is satisfied if one of the following is true:
- A is a value type, since all value types have a public default constructor (§4.1.2).
- A is a type parameter having the constructor constraint (§10.1.5).
- A is a type parameter having the value type constraint (§10.1.5).
- A is a class that is not abstract and contains an explicitly declared public constructor with no parameters.
- A is not abstract and has a default constructor (§10.11.4).
至于为什么这样设计,可能只是因为没有人将其设计为与 InternalsVisibleToAttribute 一起使用。这将需要额外的工作来指定、实施和测试该功能,我怀疑要么没有人想到它,要么被认为不值得付出努力。
这当然没有违反 CLR 中的任何内容。
所以我拿了一个 dive into Roslyn 将约束显示为:
if (typeParameter.HasConstructorConstraint && !SatisfiesConstructorConstraint(typeArgument.Type))
{
// this must be a non-abstract type with a public parameterless constructor
return false;
}
其中 SatisfiesConstructorConstraint
只是检查
HasPublicParameterlessConstructor((NamedTypeSymbol)typeArgument) && !typeArgument.IsAbstract;
如您所料,HasPublicParameterlessConstructor
只检查是否有任何构造函数是:
constructor.DeclaredAccessibility == Accessibility.Public;
他们没有为 InternalsVisibleTo
属性实现任何回旋余地。类型信息是可用的。也许打开一个问题?
在使用 InternalsVisibleTo
属性时,是否可以使用带有内部无参数构造函数的 class 来与泛型一起使用?我知道您可以使用工厂方法或反射等...来执行此操作,但最好不要使用这些方法。
如果这不可能,这是设计使然吗?如果是,为什么?
取下面的代码:
Class图书馆
[assembly: InternalsVisibleTo("testapp")]
namespace Test
{
public class MyClass
{
internal MyClass()
{
}
}
}
申请
namespace Test
{
public class GenericClass<T> where T: new()
{
// Compiles fine due to the `InternalsVisibleTo` attribute
MyClass c = new MyClass();
T t = new T();
}
public class ConsumerClass
{
// gives the error: 'MyClass' must be a non-abstract type with a public
// parameterless constructor in order to use it as parameter 'T' in the
// generic type or method 'GenericClass<T>'
GenericClass<MyClass> g;
}
}
这是设计使然。来自 the spec,第 4.4.4 节:
If the constraint is the constructor constraint
new()
, the type A must not be abstract and must have a public parameterless constructor. This is satisfied if one of the following is true:
- A is a value type, since all value types have a public default constructor (§4.1.2).
- A is a type parameter having the constructor constraint (§10.1.5).
- A is a type parameter having the value type constraint (§10.1.5).
- A is a class that is not abstract and contains an explicitly declared public constructor with no parameters.
- A is not abstract and has a default constructor (§10.11.4).
至于为什么这样设计,可能只是因为没有人将其设计为与 InternalsVisibleToAttribute 一起使用。这将需要额外的工作来指定、实施和测试该功能,我怀疑要么没有人想到它,要么被认为不值得付出努力。
这当然没有违反 CLR 中的任何内容。 所以我拿了一个 dive into Roslyn 将约束显示为:
if (typeParameter.HasConstructorConstraint && !SatisfiesConstructorConstraint(typeArgument.Type))
{
// this must be a non-abstract type with a public parameterless constructor
return false;
}
其中 SatisfiesConstructorConstraint
只是检查
HasPublicParameterlessConstructor((NamedTypeSymbol)typeArgument) && !typeArgument.IsAbstract;
如您所料,HasPublicParameterlessConstructor
只检查是否有任何构造函数是:
constructor.DeclaredAccessibility == Accessibility.Public;
他们没有为 InternalsVisibleTo
属性实现任何回旋余地。类型信息是可用的。也许打开一个问题?