Cannot Convert Lambda Expression to Type 'System.Delegate'

Cannot convert lambda expression to type 'System.Delegate' because it is not a delegate type?

You have to cast it explicitly to a Action in order for the conversion to System.Delegate to kick in.

That is:

_map.Dispatcher.BeginInvoke((Action)(() =>
{
_map.Children.Clear();
foreach (var projectedPin in pinsToAdd.Where(pin => PointIsVisibleInMap(pin.ScreenLocation, _map)))
{
_map.Children.Add(projectedPin.GetElement(ClusterTemplate));
}
}));

Cannot convert lambda expression to type 'Delegate' because it is not a delegate type

The Invoke method expects a Delegate type instance, because you use a lambda expression it cannot automatically translate the expression into something like new Delegate() because Delegate has no public constructors. Using

this.Invoke(new Action(() => {this.UpdateUserList();}));

Should solve the problem as Action is a subclass of Delegate. To get rid of the redundant new Action(...) when using Invoke you can write a set of extension methods that take as argument an Action, this way the new Action(...) will be handled by the C# compiler so you won't have to write it every time making your code cleaner.

In case you are using Invoke for some asynchronous operations that may involve other threads look into Task Parallel Library (TPL) and Task-based Asynchronous Pattern (TAP), the latter has built in support into C# and Visual Basic.NET, using await will no longer require a call to Invoke() and allow you to run some operations on the background freeing your UI.

Cannot convert lambda expression to type 'System.Delegate', Because it is not a delegate type

IMHO, it is generally better to address cross-thread needs outside of individual properties. The properties themselves should be simple, just calling GetValue() and SetValue(). In other words, a property getter or setter should not need to call Dispatcher.Invoke() at all.

That said, in your code example, you are seeing the error you're asking about in the property getter, because the compiler does not have enough information to infer the correct delegate type. The Dispatcher.Invoke() method simply takes as its parameter the base class Delegate. But this class has no inherent signature, which the compiler would need in order to automatically translate the lambda expression to an appropriate anonymous method and matching delegate instance.

Note that there is not a similar error in the setter. This is because you have provided the delegate type explicitly, through the use of the Action type's constructor. If you change the getter code to look more like the setter, it will work.

There are a few different syntaxes you could choose from, but this seems closest to the syntax you seem to prefer, based on the setter:

get
{
return Dispatcher.Invoke(
new Func<object>(() => GetValue(class1Property))) as Class1;
}



See related discussion at e.g. Why must a lambda expression be cast when supplied as a plain Delegate parameter (if you search Stack Overflow for the error message you're seeing, you'll find a few related questions).

Dispatcher.BeginInvoke: Cannot convert lambda to System.Delegate

Since the method takes a System.Delegate, you need to give it a specific type of delegate, declared as such. This can be done via a cast or a creation of the specified delegate via new DelegateType as follows:

_dispatcher.BeginInvoke(
new Action<MyClass>((sender) => { DoSomething(); }),
new object[] { this }
);

Also, as SLaks points out, Dispatcher.BeginInvoke takes a params array, so you can just write:

_dispatcher.BeginInvoke(
new Action<MyClass>((sender) => { DoSomething(); }),
this
);

Or, if DoSomething is a method on this object itself:

_dispatcher.BeginInvoke(new Action(this.DoSomething));

c# - Cannot convert lambda expression to delegate type; but this works in List functions

This works:

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication2
{
class Program
{
static void Main( string[] args )
{
var intList = new List<int> { 1000, 9102, 123, 41, 10, 52, 24, 8, 26 };
intList.ToArray()
.Sort( 0, 100, x => x > 27 );
}
}

public static class Ex
{
public static void Sort<T>( this T[] input, int low, int high, Func<T, bool> predicate )
{
input.ToList()
.ForEach( x => predicate( x ) );
}
}
}

Edit:

This works because the defined predicates “predicate” represents a function taking an object of T as parameter and returning a Boolean value. And all I did was to create an anonymous function matching the defined predicate…

I can’t explain why or what didn’t work in Schalks code, because I don’t know his code…

Edit 2 (add complete code sample):

If you are using the Sort(int index, int count, IComparer comparer) method of List you need an instance of IComparer to compare the list items. If you want to be able to specify the comparer as a lambda expression, you need a class implementing IComparer which internally uses a lambda expression to compare the items. (Or with .net 4.5 you can use Comparer<T>.Create Method .)

Here is a full sample:

public class Program
{
public static void Main( string[] args )
{
var idiots = new List<Idiot>
{
new Idiot { Weapons = new[] { new Weapon { Damage = 10 }, new Weapon { Damage = 20 } } },
new Idiot { Weapons = new[] { new Weapon { Damage = 6 }, new Weapon { Damage = 100 } } },
new Idiot { Weapons = new[] { new Weapon { Damage = 45 }, new Weapon { Damage = 12 } } },
new Idiot { Weapons = new[] { new Weapon { Damage = 24 }, new Weapon { Damage = 5 } } },
};

foreach ( var i in idiots )
i.Weapons.QuickSort( 0, i.Weapons.Count() - 1, ( a, b ) => a.Damage.CompareTo( b.Damage ) );

//Solution using IEnumerable{T} extension methods
idiots.ForEach( x => x.Weapons = x.Weapons.OrderBy( y => y.Damage ).ToArray() );
}
}

public static class Ex
{
public static void QuickSort<T>(this IEnumerable<T> input, int low, int high, Func<T, T, Int32> comparer)
{
input
.ToList()
.Sort( low, high, new FunctionalComparer<T>( comparer ) );
}
}

public class FunctionalComparer<T> : IComparer<T>
{
private readonly Func<T, T, Int32> comparer;

public FunctionalComparer(Func<T, T, Int32> comparer)
{
this.comparer = comparer;
}

public Int32 Compare(T x, T y)
{
return comparer( x, y );
}

public static IComparer<T> Create(Func<T, T, Int32> comparer)
{
return new FunctionalComparer<T>( comparer );
}
}

public class Idiot
{
public Weapon[] Weapons { get; set; }
}

public class Weapon
{
public Int32 Damage { get; set; }
}

FunctionalComparer implements IComparer and compares two objects based on a given lambda expression.
QuickSort creates an instance of FunctionalComparer (with the given expression) and uses this instance to sort the items.

But instead of writing all this code you could use the IEnumerable extension methods to do this.

C# Cannot convert lambda expression to type 'Delegate' because it is not a delegate type

Action is a Type of Delegate provided by the .NET framework. The Action points to a method with no parameters and does not return a value.

In your case, to make working your code, replace with Action:

private void _serialPort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
{
this.BeginInvoke((Action) (() => {
AddDataToAscii("\nSerial Error : " + e.EventType.ToString() + "\n", true); }));
}

Cannot convert lambda expression to type 'Delegate' because it is not a delegate type MVC 5

So your original code:

<div class="form-group">
@Html.LabelFor(model => model.Postcode_area_name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.TextBox(model => model.Postcode_area_name, new { disabled = "disabled", @readonly = "readonly" })
</div>
</div>

You should change it to:

<div class="form-group">
@Html.LabelFor(model => model.Postcode_area_name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.TextBoxFor(model => model.Postcode_area_name, new { @readonly = "readonly" })
</div>
</div>

Note, the addition of For on the TextBox and the removal of disabled = "disabled"

The reason for removing disabled as per @StephenMuecke

disabled controls do not submit a value

The reason for adding For is that it's extension method signature has the first parameter of an expression

Cannot convert lambda expression to type 'System.Linq.Expressions.Expression' because it is not a delegate type

You want to create the lambda with the item and prop you already declared

var lambda = Expression.Lambda<Func<MenuItem, object>>(prop, item);

You can also choose to strongly type the resulting lambda to the type of x.MenuItemId - if it is a string that would be like this:

var lambda = Expression.Lambda<Func<MenuItem, string>>(prop, item);

You would invoke the resulting lambda using Compile(), then using it where you would use a lambda otherwise.

For example, if you had a collection of MenuItem called items, and you wanted all the MenuItemId:

var compiled = lambda.Compiled(); 
var itemIds = items.Select(compiled); // roughly equivalent items.Select(x => x.MenuItemId);

I've written a little utility class (ugh, I know) to wrap this functionality:

static class Gen<TModel, TProp> {
public static Func<TModel, TProp> SelectorExpr(string propertyName) {
var pExpr = Expression.Parameter(typeof (TModel));
var mExpr = Expression.Property(pExpr, propertyName);
var lExpr = Expression.Lambda<Func<TModel, TProp>>(mExpr, pExpr);
return lExpr.Compile();
}
}

Use of above:

var results = items.Select(Gen<MenuItem, object>.SelectorExpr("MenuItemId"));


Related Topics



Leave a reply



Submit