views:

118

answers:

7

How can i solve this error msg?

static public class Blah
{
    public static T val<T>(this bool b, T v) { return b == true? v:0; }
}

error

Type of conditional expression cannot be determined because there is no implicit conversion between 'T' and 'int
+13  A: 

If you want T to be an int, accept an int and not a T. Otherwise, consider returning default(T) if b == false.

return b ? v : default(T);

If T is an int, it will return 0. If it is a reference type, it will be null. And on and on..

Anthony Pegram
+4  A: 

Why are you trying to use generics if you only want an int?

// No need to compare b to true...
public static int val(this bool b, int v) { return b ? v : 0; }

Otherwise, use default(T) as others have mentioned.

public static T val<T>(this bool b, T v) { return b ? v : default(T); }

default(T) will default to 0 for ints and other numeric values, false for bools, null for objects...

Mark Rushakoff
I suspect he wants to support int, long, double, etc so returning default(T) is probably the best option.
Ryan
+2  A: 

There is no way to do this in C#. You can do

where T: struct, and force T to be a value type, but that still isn't enough.

Or you can do

default(T), which is 0 when T is an int.

Matt Greer
Aren't you saying there's no way to do it, and then go on to list 2 ways to do it? :)
Jeff Meatball Yang
There is no way to say "T must be of a numeric type" in C#. My two approaches (which I'd use both together actually) are the best cludge you're gonna get :)Although really, I'd probably adopt an entirely different approach to this problem.
Matt Greer
@Jeff, he's saying there is no way to restict T to int, which is true. The first sample is showing how it can at least be limited to a value type. The second is showing how a default return value should be constructed, which will work for int, double, DateTime, object, Foo, etc.
Anthony Pegram
@Anthony - see my answer.
Jeff Meatball Yang
+2  A: 

Try replacing v : 0 with v : default(T) , if you have a good reason for generics. If you need to restrict it to int, then you're not writing a generic class.

JasonTrue
My guess is he doesn't really want int, but all numeric types (long, short, double, etc).
Matt Greer
I wish we had that option, sometimes. (Or constraints to types that support certain mathematical operators).
JasonTrue
+5  A: 

If you want to return the "default" value for T:

public static T val<T>(this bool b, T v) { return b == true? v : default(T); }

Default Values Table
default Keyword in Generic Code

Cameron MacFarland
+1  A: 

If there's only valid type for T then it shouldn't be generic:

public static int val(this bool b, int v)
{
    return b ? v : 0;
}

If you want this to work for any value type you could do this:

public static int val<T>(this bool b, T v) where T : struct
{
    return b ? v : default(T);
}
Lee
There's no particular reason that this code needs the `where T : struct`.
Adam Robinson
+1  A: 

Srsly!

To "restrict T to int" you take advantage of a special compiler feature known as strong-typing:

static public class Blah
{
    public static int val(this bool b, int v) { return b == true? v:0; }
}

Tada! :)

Seriously, why are you using generics?

Jeff Meatball Yang