How to cast Predicate<T> to Func<T, bool> [duplicate] - c#

I have a class with a member Predicate which I would like to use in a Linq expression:
using System.Linq;
class MyClass
{
public bool DoAllHaveSomeProperty()
{
return m_instrumentList.All(m_filterExpression);
}
private IEnumerable<Instrument> m_instrumentList;
private Predicate<Instrument> m_filterExpression;
}
As I read that "Predicate<T> is [...] completely equivalent to Func<T, bool>" (see here), I would expect this to work, since All takes in as argument: Func<Instrument, bool> predicate.
However, I get the error:
Argument 2: cannot convert from 'System.Predicate<MyNamespace.Instrument>' to 'System.Type'
Is there a way to convert the predicate to an argument that this function will swallow?

The two types represent the same logical signature, but that doesn't mean they're just interchangable. A straight assignment won't work, for example - but you can create a new Func<T, bool> from the Predicate<T, bool>. Sample code:
Predicate<string> pred = x => x.Length > 10;
// Func<string, bool> func = pred; // Error
Func<string, bool> func = new Func<string, bool>(pred); // Okay
This is a bit like having two enum types with the same values - you can convert between them, but you have to do so explicitly. They're still separate types.
In your case, this means you could write:
public bool DoAllHaveSomeProperty()
{
return m_instrumentList.All(new Func<T, bool>(m_filterExpression));
}
The lambda expression approach suggested by other answers will work too, of course.

public bool DoAllHaveSomeProperty()
{
return m_instrumentList.All(i => m_filterExpression(i));
}

You can convert a predicate to a method by calling Invoke. All delegates have this member. Delegates don't have structural identity, but methods can be converted to matching delegates. This fix has a minor performance cost, as it adds an extra layer of indirection. However, most solutions to this problem have that problem. Eric Lippert discusses this in more detail at https://web.archive.org/web/20140625132124/http://blog.coverity.com/2014/06/18/delegates-structural-identity/ .
In your specific case, replace return m_instrumentList.All(m_filterExpression); with return m_instrumentList.All(m_filterExpression.Invoke);
Sample code demonstrating the actual problem.
void Main()
{
Predicate<int> t1 = Foo;
Func<int,bool> t2 = Foo;
Predicate<int> t3 = t2.Invoke; //Legal
Func<int,bool> t4 = t1.Invoke; //Legal
Predicate<int> t5 = t2; //Illegal
Func<int,bool> t6 = t1; //Illegal
}
bool Foo(int x)
{
return x > 20;
}

return m_instrumentList.All(i => m_filterExpression(i));

Since there are a lot of answers i will add one more just for fun.
If you want your code to compile you can use extention methods
//Original Code
class MyClass4
{
public bool DoAllHaveSomeProperty()
{
return m_instrumentList.All(m_filterExpression);
}
private IEnumerable<Instrument> m_instrumentList;
private Predicate<Instrument> m_filterExpression;
}
Add this class in the same namespace
public static class MyExtentions
{
public static bool All(this IEnumerable<Instrument> enumer, Predicate<Instrument> pred)
{
return enumer.All(e => pred(e));
}
}

As Brian said, you can convert a predicate to a method via Invoke:
public bool DoAllHaveSomeProperty()
{
return m_instrumentList.All(m_filterExpression.Invoke);
}

Related

How can I find out the type of data from the generic type

I have a method in which I send two arguments of the same type and I need to fold them. For example, if these are numbers, then return only the sum, and if the lines are the concatenation of these lines. How can I do it? And if I pass a type that cannot be folded, then I need to throw an exception.
public class Calcul<T>
{
public static T Add(T c1, T c2)
{
}
}
Servy said in a comment:
Don't make the method generic if it's not actually generic, and don't say the method can accept any type if it can't in fact accept any type. As you've already been told, if you want to handle a finite number of specific types, have overloads for each of those types.
to which you replied:
Alas, I showed the teacher, but he said that it was not that. He said that it should be something like an abstract calculator where for each type T you can define the operation N
You can have your method with that signature and no if blocks at all, but the Add method can't be static. You have to pass in a Func<T1, T2, TResult> where T1, T2, and TResult are the same (T):
public class Calculator<T>
{
private readonly Func<T, T, T> _func;
public Calculator(Func<T, T, T> func)
{
_func = func;
}
public T Add(T a, T b)
{
return _func(a, b);
}
}
You'd use it like this:
Func<int, int, int> intAddition = (a, b) => a + b;
var intCalculator = new Calculator<int>(intAddition);
Console.WriteLine(intCalculator.Add(1, 2)); // writes 3
Func<string, string, string> stringAddition = (a, b) => a + b;
var stringCalculator = new Calculator<string>(stringAddition);
Console.WriteLine(stringCalculator.Add("Hello ", "world")); // writes "Hello world"
Online example: https://dotnetfiddle.net/8NOBsv
This way you get to specify the logic of the Add method, and you don't have loads of overloaded methods (or awful type-checking logic inside the method like if ( typeof(T) == typeof(string) ), etc.
You can typeof(T) to get the type information always. Using that, you can use conditional statements to work your way through the logic
Example:
var type = typeof(T);
if (type == int)
{ do something ;}
Generics are used for cases like : 2 different types following the same operations but taking different input types and output types. The underlying usage is that they have the same processes. If you are using type specific processes much, then its better to overload your functions to suit your need.
Reading more into your use case:
Try overloading methods.
private static int doSomething(int n1, int n2)
{
return (n1) + (n2);
}
private static float doSomething(float n1, float n2)
{
return (n1) - (n2);
}
Here's a generic way that works as long as T supports the + operator. However, it uses runtime checking. As far as I can tell there is no way to use type constraints to check this at compile time.
Adapted from: https://stackoverflow.com/a/5997156/6713871
public class Calcul<T>
{
public static T Add(T c1, T c2)
{
return (dynamic)c1 + (dynamic)c2;
}
}
As others have said you should probably use overloads. However it's possible to do something like this
static class Calc<T>
{
public static T Add(T a, T b)
{
if (typeof(T) == typeof(int))
{
return (T)(object)((int)(object)a + (int)(object)b);
}
if (typeof(T) == typeof(uint))
{
return (T)(object)((uint)(object)a + (uint)(object)b);
}
throw new ArgumentOutOfRangeException($"Type {typeof(T).Name} is not supported.");
}
}
And call it with:
Calc<int>.Add(1 , 2); // returns 3
Calc<double>.Add(2d, 3d).Dump(); // throws exception

Confusion over a Func<> predicate expression

I have read about Func<>, which says it iss a delegate and you can use it like for example:
Func<class,bool>
means you send a class or anything and get a bool result, this is what I got!
but what does the following mean?
Func<Class, bool> predicate
I have no idea, can you make it clear for me?
The former will not compile since class is a registered keyword and can only be used for class definitions.
The latter is a Func<T, TResult> which is a function that takes a parameter of type T and returns an object of type TResult. So in your case, the function takes an object of type Class and returns a bool.
The naming of Class is unfortunate but it’s actually allowed to use that identifier for a type. The following would be an example that takes such an object of type Class and then checks a property of it, returning true or false depending on the success of the comparison.
Func<Class,bool> predicate = obj => obj.Prop == "Foo";
var x = new Class();
x.Prop = "Foo";
Console.WriteLine(predicate(x)); // true
// with the following class definition
public class Class
{
public string Prop { get; set; }
}
A Func<> object is callable, just like methods, so we can use parentheses to call it and pass the object here. This would be equivalent to a method like this:
public bool predicate(Class obj)
{
return obj.Prop == "Foo";
}
But the usual way to use Func<> is using lambda expressions to be able to create functions quickly inline. This is very commonly used in LINQ where you use lambda expressions, and as such Func<> objects, all the time:
var filtered = listOfOjects.Where(obj => obj.Prop == "Foo").ToList();
// ^^^^^^^^^^^^^^^^^^^^^^^^
// this is the predicate function from above
// so you could also pass the predicate Func from above:
var filtered = listOfObjects.Where(predicate).ToList()
Func<MyClass,bool> is a delegate type
In Func<MyClass, bool> predicate , predicate is a delegate variable.
You would normally see something like
Func<MyClass, bool> predicate = c => c.IsValid;
...
if (predicate(myClass1)) DoSomething();
That's just how you instantiate the Func. Compare to a string:
string str;
If you want to instantiate and assign it at the same time, you do something like this:
Func<string, bool> isLongerThanThree = input => input.Length > 3;
isLongerThanThree("string"); // Returns "true"
Are you referring to the word predicate?
That's just the name of a parameter. Notice the similarity:
MyMethod(int myAge)
MyMethod(List<bool> myBooleans)
MyMethod(Func<Class,bool> myPredicate)
Also notice the similarities between:
int myAge = 30;
myAge is a variable of type int who has been given the value of 30.
Func<Class,bool> myPredicate = (x => x.IsAlive);
myPredicate is a variable of type Func<Class,bool> who has been given the value of (x => x.IsAlive).
Func<> is a delegate which represents a method which return a result. C# provides signatures for up to 15 input arguments, which should be enough to represent all possible methods you will ever need :)
it is hardly event to imagine method which has 15 input arguments. Beside Func<> there are also some special version of the delegate like Predicate<T> which is nothing else that Func<in T, bool TResult> or Action<> which represent a function without return value, return value is void.
Delegates(C# Programming Guide)
You can assign any method, static or instance or even anonymous with the matching signature to the Func<>. For example:
Func<MyClass, bool> predicate = (myClass) => {return true;} //anonymoys method
public class MyClass
{
public bool MyPredicate(MyClass myClass)
{
return true;
}
public static bool MyStaticPredicate(MyClass myClass)
{
return true;
}
}
Func<MyClass, bool> predicate = new MyClass().MyPredicate;
Func<MyClass, bool> staticPredicate = MyClass.MyStaticPredicate;

Is there a way to capture a lambda expression so that it's not compile-time forced to take on an identity as either an Expression or Delegate type?

Suppose I have a complex lambda expression as follows:
x => x.A.HasValue || (x.B.HasValue && x.C == q) || (!x.C.HasValue && !x.A.HasValue) || //...expression goes on
I want to use this as an Expression<Func<T,bool> in (e.g. Linq-To-Entities) Queryable.Where method. I also want to use it in the Enumerable.Where method, but the Where method only accepts a Func<T,bool>, not an Expression<Func<T,bool>.
The lambda syntax itself can be used to generate either an Expression<Func<T,bool>> or a Func<T,bool> (or any delegate type for that matter), but in this context it cannot generate more than one at once.
For example, I can write:
public Expression<Func<Pair,bool>> PairMatchesExpression()
{
return x => x.A == x.B;
}
as easily as I can write:
public Func<Pair,bool> PairMatchesDelegate()
{
return x => x.A == x.B;
}
The problem is that I cannot use the same exact lambda expression (i.e. x => x.A == x.B) in both ways, without physically duplicating it into two separate methods with two different return types, in spite of the compiler's ability to compile it into either one.
In other words, if I'd like to use the lambda expression in the Queryable methods, then I have to use the Expression method signature. Once I do that however, I cannot use it as a Func as easily as I could have had I just declared the method return type as Func. Instead, I now have to call Compile on the Expression and then worry about caching the results manually like so:
static Func<Pair,bool> _cachedFunc;
public Func<Pair,bool> PairMatchesFunc()
{
if (_cachedFunc == null)
_cachedFunc = PairMatchesExpression().Compile();
return _cachedFunc;
}
Is there a solution to this problem so that I can use the lambda expression in a more general way without it being locked down to a particular type at compile-time?
Unfortunately, I can see no way to truly get, at compile time, a Func and an Expression from the same lambda. However, you could at least encapsulate away the difference, and you can also defer the compilation of the Func until the first time it's used. Here's a solution that makes the best of things and may meet your needs, even though it doesn't quite go all the way to what you really wanted (compile-time evaluation of both the Expression and the Func).
Please note that this works fine without using the [DelegateConstraint] attribute (from Fody.ExtraConstraints), but with it, you will get compile-time checking of the constructor parameter. The attributes make the classes act like they have a constraint where T : Delegate, which is not currently supported in C#, even though it is supported in the ILE (not sure if I'm saying that right, but you get the idea).
public class VersatileLambda<[DelegateConstraint] T> where T : class {
private readonly Expression<T> _expression;
private readonly Lazy<T> _funcLazy;
public VersatileLambda(Expression<T> expression) {
if (expression == null) {
throw new ArgumentNullException(nameof(expression));
}
_expression = expression;
_funcLazy = new Lazy<T>(expression.Compile);
}
public static implicit operator Expression<T>(VersatileLambda<T> lambda) {
return lambda?._expression;
}
public static implicit operator T(VersatileLambda<T> lambda) {
return lambda?._funcLazy.Value;
}
public Expression<T> AsExpression() { return this; }
public T AsLambda() { return this; }
}
public class WhereConstraint<[DelegateConstraint] T> : VersatileLambda<Func<T, bool>> {
public WhereConstraint(Expression<Func<T, bool>> lambda)
: base(lambda) { }
}
The beauty of the implicit conversion is that in contexts where a specific Expression<Func<>> or Func<> is expected, you don't have to do anything at all, just, use it.
Now, given an object:
public partial class MyObject {
public int Value { get; set; }
}
That is represented in the database like so:
CREATE TABLE dbo.MyObjects (
Value int NOT NULL CONSTRAINT PK_MyObjects PRIMARY KEY CLUSTERED
);
Then it works like this:
var greaterThan5 = new WhereConstraint<MyObject>(o => o.Value > 5);
// Linq to Objects
List<MyObject> list = GetObjectsList();
var filteredList = list.Where(greaterThan5).ToList(); // no special handling
// Linq to Entities
IQueryable<MyObject> myObjects = new MyObjectsContext().MyObjects;
var filteredList2 = myObjects.Where(greaterThan5).ToList(); // no special handling
If implicit conversion isn't suitable, you can cast explicitly to the target type:
var expression = (Expression<Func<MyObject, bool>>) greaterThan5;
Note that you don't really need the WhereConstraint class, or you could get rid of VersatileLambda by moving its contents to WhereConstraint, but I liked making the two separate (as now you can use VersatileLambda for something that returns other than a bool). (And this difference is largely what sets apart my answer from Diego's.) Using VersatileLambda as it is now looks like this (you can see why I wrapped it):
var vl = new VersatileLambda<Func<MyObject, bool>>(o => o.Value > 5);
I have confirmed that this works perfectly for IEnumerable as well as IQueryable, properly projecting the lambda expression into the SQL, as proven by running SQL Profiler.
Also, you can do some really cool things with expressions that can't be done with lambdas. Check this out:
public static class ExpressionHelper {
public static Expression<Func<TFrom, TTo>> Chain<TFrom, TMiddle, TTo>(
this Expression<Func<TFrom, TMiddle>> first,
Expression<Func<TMiddle, TTo>> second
) {
return Expression.Lambda<Func<TFrom, TTo>>(
new SwapVisitor(second.Parameters[0], first.Body).Visit(second.Body),
first.Parameters
);
}
// this method thanks to Marc Gravell
private class SwapVisitor : ExpressionVisitor {
private readonly Expression _from;
private readonly Expression _to;
public SwapVisitor(Expression from, Expression to) {
_from = from;
_to = to;
}
public override Expression Visit(Expression node) {
return node == _from ? _to : base.Visit(node);
}
}
}
var valueSelector = new Expression<Func<MyTable, int>>(o => o.Value);
var intSelector = new Expression<Func<int, bool>>(x => x > 5);
var selector = valueSelector.Chain<MyTable, int, bool>(intSelector);
You can create an overload of Chain that takes a VersatileLambda as the first parameter, and returns a VersatileLambda. Now you're really sizzling along.
You could create a wrapper class. Something like this:
public class FuncExtensionWrap<T>
{
private readonly Expression<Func<T, bool>> exp;
private readonly Func<T, bool> func;
public FuncExtensionWrap(Expression<Func<T, bool>> exp)
{
this.exp = exp;
this.func = exp.Compile();
}
public Expression<Func<T, bool>> AsExp()
{
return this;
}
public Func<T, bool> AsFunc()
{
return this;
}
public static implicit operator Expression<Func<T, bool>>(FuncExtensionWrap<T> w)
{
if (w == null)
return null;
return w.exp;
}
public static implicit operator Func<T, bool>(FuncExtensionWrap<T> w)
{
if (w == null)
return null;
return w.func;
}
}
And then it would be used like this:
static readonly FuncExtensionWrap<int> expWrap = new FuncExtensionWrap<int>(i => i == 2);
// As expression
Expression<Func<int, bool>> exp = expWrap;
Console.WriteLine(exp.Compile()(2));
// As expression (another way)
Console.WriteLine(expWrap.AsExp().Compile()(2));
// As function
Func<int, bool> func = expWrap;
Console.WriteLine(func(1));
// As function(another way)
Console.WriteLine(expWrap.AsFunc()(2));
Here is one workaround. It generates an explicit class for the expression (as the compiler would do under the hood anyway with lambda expressions that require a function closure) instead of just a method, and it compiles the expression in a static constructor so it doesn't have any race conditions that could result in multiple compilations. This workaround still incurs an additional runtime delay as a result of the Compile call which could otherwise be offloaded to build-time, but at least it's guaranteed to run only once using this pattern.
Given a type to be used in the expression:
public class SomeClass
{
public int A { get; set; }
public int? B { get; set; }
}
Build an inner class instead of a method, naming it whatever you would have named the method:
static class SomeClassMeetsConditionName
{
private static Expression<Func<SomeClass,bool>> _expression;
private static Func<SomeClass,bool> _delegate;
static SomeClassMeetsConditionName()
{
_expression = x => (x.A > 3 && !x.B.HasValue) || (x.B.HasValue && x.B.Value > 5);
_delegate = _expression.Compile();
}
public static Expression<Func<SomeClass, bool>> Expression { get { return _expression; } }
public static Func<SomeClass, bool> Delegate { get { return _delegate; } }
}
Then instead of using Where( SomeClassMeetsConditionName() ), you simply pass SomeClassMeetsConditionName followed by either .Delegate or .Expression, depending on the context:
public void Test()
{
IEnumerable<SomeClass> list = GetList();
IQueryable<SomeClass> repo = GetQuery();
var r0 = list.Where( SomeClassMeetsConditionName.Delegate );
var r1 = repo.Where( SomeClassMeetsConditionName.Expression );
}
As an inner class, it could be given an access level just like a method and accessed just like a method, and even collapsed all at once like a method, so if you can stand to look at the class instead of a method, this is a functional workaround. It could even be made into a code template.

C# Continuation Monad Implementation

I have been working on allowing function chaining. I have created a class called continuationmonad which takes a value, and a function from a => b. This allows me to use fmap and bind to chain these together. I have also used lazy to allowed calls to be defered where possible.
Is this class really the continuation monad or is it something else. I am finding it hard to find good literature which is not is Haskell.
Also any comments on how to improve / correct this.
using NUnit.Framework;
using System;
namespace Monads
{
public class Continuation<Input, Output>{
public Continuation(Input value, Func<Input,Output> function){
this.value = new Lazy<Input>( () => value);
this.function = function;
}
public Continuation(Lazy<Input> value, Func<Input,Output> function){
this.value = value;
this.function = function;
}
public Continuation<Output, Result> FMap<Result>(Func<Output, Result> map){
return new Continuation<Output, Result>(new Lazy<Output>( () => Run() ), x => map(x));
}
public Continuation<Output,Result> Bind<Result>(Func<Output, Continuation<Output, Result>> f){
return f(Run());
}
public Output Run(){
return function(value.Value);
}
private Func<Input, Output> function;
private Lazy<Input> value;
}
public static class ContinuationExtension{
public static Continuation<A,B> Unit<A,B>(this Func<A,B> f, A value){
return new Continuation<A, B>(value,f);
}
public static Continuation<A,B> Unit<A,B>(this A value,Func<A,B> f){
return new Continuation<A, B>(value,f);
}
}
[TestFixture]
public class MonadTests
{
public Continuation<int,int> Wrapped(int value){
return new Continuation<int,int>(value, x => x * 10);
}
[Test]
public void ContinuationMonadTests()
{
var number = 42;
var result = number.Unit(x => x + 8).FMap(x => x * 2).Bind(Wrapped).Run();
Console.WriteLine(result);
}
}
}
This is not the continuation monad. You are much closer to the Haskell Monad instance for functions.
You aren't getting anything that you couldn't get just from using Lazy<>. Since you have provided the input when you build an instance of your class, you aren't building functions, you are building values that are determined by a computation that hasn't been evaluated yet. Lazy<> delays the evaluation of computation until the value is needed.
Let's put together something like the Haskell Monad instance for functions in c#. LINQ syntax has established the convention for Monads in c#. They should have:
a Select extension method analogous to a Haskell Functor's fmap
a SelectMany extension method analogous to Haskell's Monad's >>=
an additional SelectMany that LINQ syntax uses. This takes an additional function that combines the value from two steps together.
Unfortunately, there's no convention for what the analog of a Monad's return should be called; we'll call ours Constant. Unfortunately, Constant won't be very convenient because c#'s type inference won't be able to figure out the types.
public static class Function
{
public static Func<TIn, TOut> Constant<TIn, TOut>(TOut result)
{
return x => result;
}
public static Func<TIn, TOut> Select<TIn, TMid, TOut>(
this Func<TIn, TMid> func,
Func<TMid, TOut> proj)
{
return x => proj(func(x));
}
public static Func<TIn, TOut> SelectMany<TIn, TMid, TOut>(
this Func<TIn, TMid> func,
Func<TMid, Func<TIn, TOut>> proj)
{
return x => proj(func(x))(x);
}
public static Func<TIn, TOut> SelectMany<TIn, TMid1, TMid2, TOut>(
this Func<TIn, TMid1> func,
Func<TMid1, Func<TIn, TMid2>> proj1,
Func<TMid1, TMid2, TOut> proj2)
{
return x => {
var mid1 = func(x);
var mid2 = proj1(mid1)(x);
return proj2(mid1, mid2);
};
}
}
Note that defining these extension methods only lets you interact with something like it's a Monad, it doesn't let you write code that's generic over the specific Monad being used. There's a sketch of how to do that in the second half of this answer.
This might be a bit opinion based but I'll try to give you my 5ct anyway.
Let's have a look at your class and their instances:
It includes a value and a function where you (tried) to make it all a lazy.
From a theoretical view I can see no difference to Lazy<T> on first glance:
You can surely convert one of your Continuation<Input,Output> to just a Lazy<Output>.
The same is true for the reverse: given some lazy value a you can make a instance with just
new Continuation(a, x => x)
So to me it seems that you just reinvented Lazy (which is an monad, in Haskell you would call it Identity.
The Cont monad is not really easy to crasp but it's really more related to .net-Events or .net-Observables. The datastructure itself would be like
Func<Func<Input,Output>, Output>
Where you pass in a continuation Func<Input,Output> to some internal calculation and then the struture than will call it when it has calculated an input Input to get the final result.
This might be a bit cryptic but one .net application are the Async workflows F# uses and which stood model for C#s async/await behaviour in some sense.
I have some material I used for a talk on a simpified version of this monad in C# on github maybe you'll find it interesting.
I have created a very comprehensive introduction to the Continuation monad that you can Find Here Discovering the Continuation Monad in C#
Also you can find a.Net Fiddle here
I Repeat it in summary here
Starting from an initial Function
int Square(int x ){return (x * x);}
Use Callback and remove return type
public static void Square(int x, Action<int> callback)
{
callback(x * x);
}
Curry the Callback
public static Action<Action<int>> Square(int x)
{
return (callback) => { callback(x * x); };
}
Generalize the returned Continuation
public static Func<Func<int,T>,T> Square<T>(int x)
{
return (callback) => { callback(x * x); };
}
Extract the Continuation Structure Also Known As the Return Method of the monad. That is Give me a value and i will give you a Monad for this value
//((U→ T) → T)
delegate T Cont<U, T>(Func<U, T> f);
public static Cont<U, T> ToContinuation<U, T>(this U x)
{
return (callback) => callback(x);
}
square.ToContinuation<Func<int, int>, int>()
Add The bind Monadic method and thus Complete the Monad.That is Give me a Two Monads and i will combine them to a new monad
((A→ T) → T)→( A→((B→ T) → T))→ ((B→ T) → T)
public static Cont<V, Answer> Bind<T, U, V, Answer>(
this Cont<T, Answer> m,
Func<T, Cont<U, Answer>> k,
Func<T, U, V> selector)
{
return (Func<V, Answer> c) =>
m(t => k(t)(y => c(selector(t, y))));
}

C#/Fixing Operators for Generics

I tried to apply operators on Generics (for my example ,multiplication)
public static List<TOutput> Conversion<TOutput>(List<TInput> input)
{
List<TOutput> outList = new List<TOutput>();
foreach(TInput tinput in input)
{
double dbl = tinput *tinput;
outList.Add(dbl);
}
return outList;
}
Any workaround for fixing it?
Not possible without reflecting upon the type. There is some code that does this available as part of MiscUtil.
This is now possible in C# 11 / .NET 7 (or above):
public static List<TOutput> Conversion<TInput, TOutput>(List<TInput> input)
where TInput : IMultiplyOperators<TInput, TInput, TOutput>
{
List<TOutput> outList = new List<TOutput>();
foreach (TInput tinput in input)
{
TOutput product = tinput * tinput;
outList.Add(product);
}
return outList;
}
The compiler shouldn't allow you to assign a double to an unknown type:
outList.Add(dbl);
For all it knows, you could be trying to assign a dbl to a type of FluxCapacitor. Your code is trying to accomplish two incompatible things: to return a list of generic (unknown) type, and 2) to force that type to be a double. This doesn't make sense, which is why you're having difficulty. You can use reflection (as Porges pointed out with an excellent link) to solve this dynamically, but you really need to ask yourself: why are you trying to assign a floating point number to a class that has an unknown type? The calling code could be asking for a result of List<bool>. How much sense would it make to try to assign
double foo = 1.5;
bool bar = foo;
? Zero. You can make the compiler do anything with enough somersaults, but you need to reevaluate the purpose of your routine, why you're trying to put a specific datatype into a generic one, and whether or not this routine needs to return a generic list.
The "MiscUtil" answer (already accepted) would be my first choice ;-p
You might also consider LINQ at the caller:
var prodList = originalList.Select(x=>x*x).ToList();
Since the caller knows the type (assuming it isn't itself generic, this should work.
Just for completeness, another option here (in 4.0) is dynamic:
public static List<TOutput> Conversion<TOutput>(List<TInput> input)
{
List<TOutput> outList = new List<TOutput>();
foreach(TInput tinput in input)
{
TOutput square = (dynamic)tinput * (dynamic)tinput;
outList.Add(square);
}
return outList;
}
You could use a cached lambda to do your calculation (and/or conversion).
This doesn't require the DLR or the dynamic keyword, so it's perfectly usable in C# 3.0
static class Squarer<T>
{
private static readonly Func<T, T> _square;
static Squarer()
{
ParameterExpression x = Expression.Parameter(typeof(T), "x");
_square = Expression.Lambda<Func<T, T>>(
Expression.Multiply(x, x),
x).Compile();
}
public static T Square(T value)
{
return _square.Invoke(value);
}
}
Console.WriteLine(Squarer<double>.Square(1234.5678));
Console.WriteLine(Squarer<decimal>.Square(1234.5678m));
Console.WriteLine(Squarer<int>.Square(1234));

Categories