使用英语阅读

通过


IL2122:类型“type”不是程序集限定的类型。 用于动态访问类型的类型名称字符串应为程序集限定的名称

原因

表示动态访问类型的类型名称字符串必须是程序集限定的。 否则,Type.GetType 的查找语义将使用 Type.GetType 调用网站和核心库搜索程序集。 具有 Type.GetType 调用网站的程序集可能与使用 DynamicallyAccessedMembersAttribute 将类型名称字符串传递到某个位置的程序集不同,因此工具无法确定要搜索的程序集。

示例

// In Assembly 1
void TestInvalidTypeName()
{
    // IL2122: Type 'MyType' is not assembly qualified. Type name strings used for dynamically accessing a type should be assembly qualified.
    RequirePublicMethodOnAType("MyType");
}

void ForwardTypeNameToAnotherMethod(
    [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)]
    string typeName)
{
    MyTypeFromAnotherAssembly.GetType(typeName);
}
// In Assembly 2
public class MyTypeFromAnotherAssembly
{
    void GetTypeAndSearchThroughMethods(
        [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)]
        string typeName)
    {
        Type.GetType(typeName).GetMethods();
    }
}

class MyType
{
    // ...
}

在非修整应用中,在运行时,Type.GetType 调用将在程序集 2 中发现 MyType。 但是,剪裁将删除 MyType,因为剪裁工具没有足够的信息来确定在运行时找到该类型的位置。

若要解决此问题,请考虑改用完全限定的类型名称:

RequirePublicMethodsOnAType("MyType,Assembly2");

另一个选项是将非限定类型名称字符串直接传递给 Type.GetType,并避免对 string 进行注释:

var type = Type.GetType("MyType");

void SearchThroughMethods(
    [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)]
    Type type)
{
    type.GetMethods();
}

这为剪裁工具提供了足够的信息,以便使用 GetType(String) 在运行时具有的相同语义查找类型,从而导致保留此类型(和本示例中的公共方法)。