Bug 49053 - Accessing count property of the queryable collection leads to “No method count exist invalid operation exception”
Summary: Accessing count property of the queryable collection leads to “No method coun...
Status: RESOLVED ANSWERED
Alias: None
Product: iOS
Classification: Xamarin
Component: Tools (show other bugs)
Version: master
Hardware: PC Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
: 51259 (view as bug list)
Depends on:
Blocks:
 
Reported: 2016-12-05 21:22 UTC by Sebastien Pouliot
Modified: 2017-01-06 18:29 UTC (History)
4 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED ANSWERED

Description Sebastien Pouliot 2016-12-05 21:22:07 UTC
Split of bug #37563, comment #17 onward.

Test case:
https://bugzilla.xamarin.com/attachment.cgi?id=17575
Comment 1 Sebastien Pouliot 2016-12-05 21:44:47 UTC
The linker does a static analysis of the application to remove code that is not required. This does not work, at least without additional efforts, when using dynamic code, like:

            var exp =  (Int32)queryable.Provider.Execute(
                Expression.Call(
                    typeof(Queryable),
                    "Count",
                    new Type[] { sourceType },
                    new Expression[] { queryable.Expression }
                    ));

In such case you are responsible (as an application or library developer) to either

1. Disable the linker (globally or partially); or, better

2. Provide the linker with hints for the code that will be required, dynamically, at runtime.

E.g. adding this line inside Main.cs

> [assembly: Preserve (typeof (System.Linq.Queryable), AllMembers = true)]

solve the above issue. IOW the linker now knows that `Queryable` will be used dynamically and that the type, and it's members (and everything that it needs) will be preserved.

In case you have no direct dependency on Xamarin.iOS.dll (e.g. PCL) then you can define your own `PreserveAttribute` class. The linker will accept your own version of the attribute (as long as the signature match) in any namespace.
Comment 2 Divakar 2017-01-06 05:39:11 UTC
Hi Team,

Thanks for the update and workaround.

The first workaround is fine and we are already aware of it. Am yet to try the second one by writing my own preserve attribute. 

But my question is different, I expect a solution for the reported issue rather than a workaround. This was working fine in earlier versions of Xamarin without disabling the linker or preserving, but has got broken again. It's a long story to explain. 

As customers we expect an issue to be fixed but what happens nowadays is a workaround is given and the ticket is marked as Resolved. Can you please let us know when this will be internally fixed in Xamarin? Or do you mean that this bug cannot be fixed in Xamarin? 
 
I hope you find this logic well. We can not inform all our customer that there is a linker problem and you have to use this workaround in your sample. So we need an internal fix for this.

Also, we have experienced one more issue called "No method 'OfType' exists on type 'System.Linq.Queryable'" while accessing System.Linq.Queryable.

So, could you please provide the fixes for the above-mentioned issue asap?
Comment 3 Sebastien Pouliot 2017-01-06 14:08:15 UTC
Sorry if I was not clear.

> rather than a workaround.

Using [Preserve] is a linker feature that is required if you're using reflection, including LINQ's Expression.

It's by design, the linker static analysis cannot predict what would be required in such cases. The solution is to give the linker extra information that will let it include code using dynamically.

The other alternatives are to:
- stop using refection / Expression; or
- disable the linker (per assembly or globally).


> This was working fine in earlier versions of Xamarin

Maybe, maybe not. Using reflection, including Expression, has (and will) never be *safe* without preserving the required code. 

What can happen is that other code, e.g. in your code or inside the BCL itself, used the same types/methods (without an Expression) so the linker already had them marked.

Since we're moving to use more of MS reference (and corefx) source code the internals of the BCL are quite different today.


> We can not inform all our customer

Then don't. Include the line:

   [assembly: Preserve (typeof (System.Linq.Queryable), AllMembers = true)]

inside your own assembly. It's your code that is using Expression so the attribute should be part of your own assembly (not your customers).


> we have experienced one more issue called "No method 'OfType' exists on type 'System.Linq.Queryable'"

Please file a different bug, include a test case and we will investigate.
Comment 4 Brendan Zagaeski (Xamarin Team, assistant) 2017-01-06 18:29:12 UTC
*** Bug 51259 has been marked as a duplicate of this bug. ***