2

I've used a converter to change vb to c# and one of the lines originally is:

Dim roles = System.Web.Security.Roles.GetAllRoles()
Dim roleNames() As String = roles.Where(Function(x) x.ToLower() <> "Admin").ToArray()

When the conversion returns I get:

dynamic roles = System.Web.Security.Roles.GetAllRoles();
string[] roleNames = roles.Where(x => x.ToLower() != "Admin").ToArray();

Which then throws the error:

Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type.

I've tried a few different ways and a few different converters, but I dont get any different results.

Why does it work fine in vb and not in c# if the conversion is correct?

X3074861X
  • 3,709
  • 5
  • 32
  • 45
T.J.
  • 31
  • 5
  • Late binding with C# (using `dynamic`) can't pick up on extension methods. Try changing `dynamic` to `var` and see what happens. – willaien Jan 21 '16 at 21:19
  • @willaien It actually fails on trying to use a lambda before it even gets to trying to resolve the extension method. – Servy Jan 21 '16 at 21:21
  • That's a simple fix. You know in vb what Dim does I would assume so how is it declared in C# ... I would worry about learning the syntax instead of converting code... – Trevor Jan 21 '16 at 21:22
  • @Servy: Fair enough. It would then blow up on the extension method as well. This is why code converts should be treated gingerly and reviewed. – willaien Jan 21 '16 at 21:23
  • 2
    just a quick observation but would x.ToLower() ever = "Admin"? Shouldn't that be x.ToLower() != "admin" as the .ToLower() would convert all casing as such? – Charles May Jan 21 '16 at 21:23
  • 1
    @CharlesMay Yet another reason to use a case insensitive comparer rather than trying to hack it with `ToLower`. – Servy Jan 21 '16 at 21:23
  • Dim wasn't the issue @Codexer, but thanks for the useful advice... – T.J. Jan 22 '16 at 02:00
  • roles.Where(x => x.ToLower() != "Admin") Is where it keep blowing up. – T.J. Jan 22 '16 at 02:01

3 Answers3

7

Why does it work fine in vb and not in c# if the conversion is correct?

Because the conversion isn't correct. You shouldn't be using dynamic here.

var roles = System.Web.Security.Roles.GetAllRoles(); 
string[] roleNames = roles.Where(x => x.ToLower() != "Admin").ToArray();
Servy
  • 202,030
  • 26
  • 332
  • 449
5

Replace the dynamic with var.

As Servy points out in their comment this happens because the VB code is compiled with strict off and the only way that C# can avoid type checking is with dynamic. As there's no compile time checking, should you get your converted code to compile with dynamic there's a good chance you'll hit run time errors.

If you turn strict on before the conversion process you should get better results, but you'll probably have to fix all the errors that that generates first.

For more information on the dynamic keyword see here and here

Community
  • 1
  • 1
ChrisF
  • 134,786
  • 31
  • 255
  • 325
  • It makes the mistake because the VB code is compiled with strict off, and in virtually all cases, the only way to replicate that in C# is with `dynamic`. Worse still, the conversions will only rarely fail to compile (namely when lambdas and extension methods are involved). – Servy Jan 21 '16 at 21:19
0

One option is to explicitly create roles as a string array:

string[] roles = System.Web.Security.Roles.GetAllRoles();
string[] roleNames = roles.Where(x => x.ToLower() != "Admin").ToArray();
maniak1982
  • 707
  • 2
  • 7
  • 23