Skip to content

Why importing generic field should use assembly resolver to resolve original FieldDef #445

@wwh1004

Description

@wwh1004

public IField Import(FieldInfo fieldInfo, bool forceFixSignature) {

if (origField.FieldType.ContainsGenericParameters) {
	var origDeclType = origField.DeclaringType;
	var asm = module.Context.AssemblyResolver.Resolve(origDeclType.Module.Assembly.GetName(), module);
	if (asm is null || asm.FullName != origDeclType.Assembly.FullName)
		throw new Exception("Couldn't resolve the correct assembly");
	var mod = asm.FindModule(origDeclType.Module.ScopeName) as ModuleDefMD;
	if (mod is null)
		throw new Exception("Couldn't resolve the correct module");
	var fieldDef = mod.ResolveField((uint)(origField.MetadataToken & 0x00FFFFFF));
	if (fieldDef is null)
		throw new Exception("Couldn't resolve the correct field");

	var fieldSig = new FieldSig(Import(fieldDef.FieldSig.GetFieldType()));
	fieldRef = module.UpdateRowId(new MemberRefUser(module, fieldInfo.Name, fieldSig, parent));
}

Sometimes it is difficult to resolve assembly and importer will throw if AssemblyResolver is null.
e.g. Target assembly is memory loaded.

I don't know why generic field should be treated differently. I find it is changed in a old commit 4ebebc1
I've tested many cases of generic field and the old code (same behavior as importing generic method) can return the same result.

Test code:

static class G<T1, T2> where T1 : class {
 static volatile T1 Value1;
 static volatile IDictionary<T1, T2> Value2;

 static void MethodToImport<T3>() where T3 : class {
  Value1 = null;
  Value2 = null;
  G<string, string>.Value1 = null;
  G<string, string>.Value2 = null;
  G<string, T3>.Value1 = null;
  G<string, T3>.Value2 = null;
  G<T3, T3>.Value1 = null;
  G<T3, T3>.Value2 = null;
 }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions