Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support ref returns (c# 7) #568

Closed
tzachshabtay opened this issue Jan 7, 2018 · 4 comments
Closed

Support ref returns (c# 7) #568

tzachshabtay opened this issue Jan 7, 2018 · 4 comments

Comments

@tzachshabtay
Copy link

My interface which I'm trying to mock has a ref return in it:

ref ModelMatrices GetModelMatrices();

The code for the interface is here:

https://github.com/tzachshabtay/MonoAGS/blob/734b13f467d33b5099b81d52f3d391448b41b9eb/Source/AGS.API/Objects/IModelMatrixComponent.cs#L36

If I just create my mock without overriding the behavior and then call GetModelMatrices on it, it crashes with:

System.InvalidProgramException : Invalid IL code in Castle.Proxies.IObjectProxy:GetModelMatrices (): IL_0030: ret

And I don't see how I can setup the return?
If I do:
_myMock.Setup(m => m.GetModelMatrices()).Returns(ref something);

I get a compile error: Error CS8153: An expression tree lambda may not contain a call to a method, property, or indexer that returns by reference (CS8153) (Tests)

@stakx
Copy link
Contributor

stakx commented Jan 7, 2018

Hi @tzachshabtay, thank you for reporting this. Quite frankly, my initial gut feeling is that it will be impossible to realize this feature in Moq. First, there are two roadblocks to be overcome before we could even start work in Moq:

Road block 1: DynamicProxy does not currently appear to support ref returns.

If I just create my mock without overriding the behavior and then call GetModelMatrices on it, it crashes with:

System.InvalidProgramException : Invalid IL code in Castle.Proxies.IObjectProxy:GetModelMatrices (): IL_0030: ret

This is an issue with Castle DynamicProxy (upon which Moq relies to generate mock proxy types), which apparently does not currently support ref returns.

We could raise an issue over at https://github.com/castleproject/Core/issues to discuss this feature, and possibly submit a PR with the necessary changes. (However I'm not certain at this point whether it would even be possible for DynamicProxy to properly support ref returns.)

Roadblock 2: The C# compiler does not allow ref returns in LINQ expression trees.

And I don't see how I can setup the return?
If I do:
_myMock.Setup(m => m.GetModelMatrices()).Returns(ref something);

I get a compile error: Error CS8153: An expression tree lambda may not contain a call to a method, property, or indexer that returns by reference (CS8153) (Tests)

This in turn is a current limitation of the C# language / compiler. There's not much we can do in Moq. I suggest you add your vote in dotnet/csharplang#158 if you want this changed.

@tzachshabtay
Copy link
Author

@stakx can you open an issue for DynamicProxy then?
Thanks.

@stakx
Copy link
Contributor

stakx commented Jan 8, 2018

@tzachshabtay: Perhaps I will, just to get confirmation what I already suspect (with a fairly high degree of confidence): that DynamicProxy won't be able to support ref returns, due to the way how its central IInvocation and IInterceptor abstractions are designed.

Moq 5 just might be able to support ref returns (@kzu - correct?), but don't get your hopes up for Moq 4. :-/

@kzu
Copy link
Contributor

kzu commented Jan 8, 2018 via email

tzachshabtay added a commit to tzachshabtay/MonoAGS that referenced this issue Jan 11, 2018
Refactored matrix updating logic to its own class. This means we can
now mock it for our tests which helps us workaround the fact that we
can no longer mock the ref return as moq does not support it
(devlooped/moq#568).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants