question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Public GenericParameter constructor that takes context-free position

See original GitHub issue

In a project using Mono.Cecil to write IL, I need to specify member references such as System.Collections.Generic.Dictionary`2<string, string>::.ctor(class System.Collections.Generic.IEqualityComparer`1<!0>) Because the corresponding reference assemblies may not be available at the time, I’m not loading mscorlib.dll/System.Collections.dll/netstandard.dll etc. Just emitting the correct assembly name reference (if needed) and the correct IL. That requires me to construct the type specification for System.Collections.Generic.IEqualityComparer`1<!0> without having a GenericParameterCollection from the reference assembly to set the generic parameter position.

The only option so that the project is not blocked is to use reflection to get the Position property set to something other than -1 which of course serialization chokes on:

var genericParameter0 = (GenericParameter)typeof(GenericParameter)
    .GetConstructor(
        BindingFlags.NonPublic | BindingFlags.Instance,
        null,
        new[] { typeof(int), typeof(GenericParameterType), typeof(ModuleDefinition) },
        null)
    .Invoke(new object[] { 0, GenericParameterType.Type, module });

// Instantiate IEqualityComparer<> with Dictionary<,>'s TKey
var equalityComparer = new TypeReference(
    "System.Collections.Generic",
    "IEqualityComparer`1",
    module,
    scope: assemblyContainingSystemCollections);

var equalityComparerInstantiation = new GenericInstanceType(equalityComparer)
{
    GenericArguments = { genericParameter0 }
};


il.Emit(OpCodes.Newobj, new MethodReference(
    ".ctor",
    returnType: dictionaryField.Module.TypeSystem.Void,
    declaringType: dictionaryField.FieldType)
{
    HasThis = true,
    Parameters =
    {
        new ParameterDefinition(module.ImportReference(equalityComparerInstantiation))
    }
});

Ideally, this constructor would be public:

https://github.com/jbevain/cecil/blob/12da1bf7e0e10278e05eeb23adfc72760bbb6668/Mono.Cecil/GenericParameter.cs#L188-L198

namespace Mono.Cecil
{
    public sealed class GenericParameter : TypeReference, ICustomAttributeProvider
    {
        public GenericParameter(IGenericParameterProvider owner);

        public GenericParameter(string name, IGenericParameterProvider owner);

+       public GenericParameter(
+           int position,
+           GenericParameterType type,
+           ModuleDefinition module);
    }
}

Does this sound good to you?

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:13 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
jbevaincommented, Sep 12, 2019

Maybe dnlib would work best for you?

https://github.com/0xd4d/dnlib

1reaction
jbevaincommented, Aug 26, 2019

You want to emit:

newobj instance void class System.Collections.Generic.Dictionary`2<string, string>::.ctor(class System.Collections.Generic.IEqualityComparer`1<!0>)

Based on your code, the declaringType for the ctor is:

dictionaryField.FieldType

Which means that dictionaryField.FieldType is a GenericInstanceType that is instantiating Dictionary<TKey,TValue> with <string, string>.

So the ElementType of the GenericInstanceType is going to be a TypeReference, it’s going to have a .GenericParameters collection.

Basically, you want to use the [0] of the GenericParameters of that instead of crafting your own.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Restricting a generic type parameters to have a specific ...
If we consider constructors as part of the implementation, then, constraining the constructor of a generic type parameter is not a very generic ......
Read more >
Generic Constructors and Interfaces in Java
Generics make a class, interface and, method, consider all (reference) types that are given dynamically as parameters.
Read more >
Constraints on generic type parameters (C++/CLI)
Constraints are applied to type parameters to place limitations on the types that can be used as arguments for a generic type or...
Read more >
4. Generics - Programming C# 8.0 [Book]
In this case, I've used it as the type of a constructor argument, ... define local variables of type T . And you're...
Read more >
Generic Types - Learning the Java Language
A generic type is a generic class or interface that is parameterized over types. The following Box class will be modified to demonstrate...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found