Skip to content

Proxies using Records derived from a base generic record broken using .NET 6 compiler #632

@CesarD

Description

@CesarD

Similar to what occurred in #601, when trying to mock (with Moq) records derived from a base generic record, an exception is thrown.

Repro code:

var mock1 = new Mock<MyDerivedRecord>();
var mock2 = new Mock<MyDerivedGenericRecord>();

var a = mock1.Object;
var b = mock2.Object;

public abstract record MyBaseRecord
{
}

public abstract record MyBaseGenericRecord<T>
{
	public T Prop { get; set; }
}

public record MyDerivedRecord : MyBaseRecord
{
}

public record MyDerivedGenericRecord : MyBaseGenericRecord<int>
{
}

Variable a holds the mocked object as expected, but when initializing b, the following is thrown:

System.ArgumentException
  HResult=0x80070057
  Message=Type to mock (MyDerivedGenericRecord) must be an interface, a delegate, or a non-sealed, non-static class.
  Source=Moq
  StackTrace:
   at Moq.CastleProxyFactory.CreateProxy(Type mockType, IInterceptor interceptor, Type[] interfaces, Object[] arguments) in C:\projects\moq4\src\Moq\Interception\CastleProxyFactory.cs:line 66
   at Moq.Mock`1.InitializeInstance() in C:\projects\moq4\src\Moq\Mock`1.cs:line 307
   at Moq.Mock`1.OnGetObject() in C:\projects\moq4\src\Moq\Mock`1.cs:line 326
   at Moq.Mock`1.get_Object() in C:\projects\moq4\src\Moq\Mock`1.cs:line 281
   at Program.<Main>$(String[] args) in C:\Users\Cesar\source\repos\ConsoleApp1\Program.cs:line 11

  This exception was originally thrown at this call stack:
    System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()
    System.Reflection.Emit.TypeBuilder.CreateTypeInfo()
    Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType()
    Castle.DynamicProxy.Generators.BaseClassProxyGenerator.GenerateType(string, Castle.DynamicProxy.Generators.INamingScope)
    Castle.Core.Internal.SynchronizedDictionary<TKey, TValue>.GetOrAdd(TKey, System.Func<TKey, TValue>)
    Castle.DynamicProxy.Generators.BaseProxyGenerator.GetProxyType()
    Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(System.Type, System.Type[], Castle.DynamicProxy.ProxyGenerationOptions, object[], Castle.DynamicProxy.IInterceptor[])
    Moq.CastleProxyFactory.CreateProxy(System.Type, Moq.IInterceptor, System.Type[], object[]) in CastleProxyFactory.cs

Inner Exception 1:
TypeLoadException: Return type in method 'Castle.Proxies.MyDerivedGenericRecordProxy_2.<Clone>$()' on type 'Castle.Proxies.MyDerivedGenericRecordProxy_2' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is not compatible with base type method 'MyDerivedGenericRecord.<Clone>$()'.

Originally posted by @CesarD in #601 (comment)

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions