Bug 49053

Summary: Accessing count property of the queryable collection leads to “No method count exist invalid operation exception”
Product: iOS Reporter: Sebastien Pouliot <sebastien>
Component: ToolsAssignee: Bugzilla <bugzilla>
Status: RESOLVED ANSWERED    
Severity: normal CC: cnharishkrish, divakar.subramaniam, FieldstrikeMobile, mono-bugs+monotouch
Priority: ---    
Version: master   
Target Milestone: Untriaged   
Hardware: PC   
OS: Mac OS   
Tags: Is this bug a regression?: ---
Last known good build:

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. ***