Value Types
-
C# has a Type parameter feature, such that a function / class can be used with different types of a variable at run-time. Jonny found a very intelligent use of it:
T value1 = (T)Convert.ChangeType(cameraParameterValue, typeof(T)); T value2 = (T)Convert.ChangeType(_value, typeof(T)); if ((value1 is double || value1 is float) && (value2 is double || value2 is float)) { if (Math.Abs((double)Convert.ChangeType(value1, typeof(double)) - (double)Convert.ChangeType(value2, typeof(double))) < 0.001)
As you can see, there is exactly one (i.e. 1) type parameter
T
. That is, when both calls to(T)Convert.ChangeType
have succeeded, bothvalue1
andvalue2
have the same type.Now look at the first
if
clause: do you really need to checkvalue2
?The second
if
clause with its extra manual conversion todouble
is NOT a WTF by Jonny, but of C#. You cannot simply do
if (Math.Abs(value1 - value2) < 0.001)
or
if (Math.Abs((double)value1 - (double)value2) < 0.001)
because C# fails to see the types.
-
@BernieTheBernie said in Value Types:
because C# fails to see the types.
No no, it fails to implicitly convert a Type into a particular object of type Type with the value of T. There's a difference.
Edit: if you think I'm serious.
-
ChangeType
returnsobject
, boxing your numeric types. That's why C# needs to be told to unbox it back todouble
when you want to use it as such. The whole deal is unwieldy, but that's why you don't screw around with types this way. The whole snippet is one big is .
-
I don't get it. Why in the world would you need T when at the end of it, you are just going to perform double-type operations?
-
@BernieTheBernie said in Value Types:
C# has a Type parameter feature, such that a function / class can be used with different types of a variable at run-time. Jonny found a very intelligent use of it:
T value1 = (T)Convert.ChangeType(cameraParameterValue, typeof(T)); T value2 = (T)Convert.ChangeType(_value, typeof(T)); if ((value1 is double || value1 is float) && (value2 is double || value2 is float)) { if (Math.Abs((double)Convert.ChangeType(value1, typeof(double)) - (double)Convert.ChangeType(value2, typeof(double))) < 0.001)
As you can see, there is exactly one (i.e. 1) type parameter
T
. That is, when both calls to(T)Convert.ChangeType
have succeeded, bothvalue1
andvalue2
have the same type.Now look at the first
if
clause: do you really need to checkvalue2
?The second
if
clause with its extra manual conversion todouble
is NOT a WTF by Jonny, but of C#. You cannot simply do
if (Math.Abs(value1 - value2) < 0.001)
or
if (Math.Abs((double)value1 - (double)value2) < 0.001)
because C# fails to see the types.
try:
var value1 = cameraParameterValue as double?; var value2 = _value as double?; if (value1.HasValue && value2.HasValue) { if (Math.Abs(value1.Value - value2.Value) < 0.001) { // Rest of code } }
It compiles, and inspection indicates that it is functionally equivalent to the version you provided (assuming that there is not some weird incompatibility with
Conver.ChangeType
that differs from theas
keyword.... which honestly i havent found one yet.I omitted the float check because well, that has an implicit conversion to double so
floatvalue as double?
just upcasts the float to the double and now i don't have to worry about it.
-
@Vixen Beyond this comparison for floating point values with a delta, there are other equality comparisons for non-floating values, too. So that's not the solution to the whole issue.
Just had fun with this block of code because of the unnecessary double-check in the first if-clause, plus the .Net convolution there after.
-
@BernieTheBernie said in Value Types:
there are other equality comparisons for non-floating values,
well if yah'dve mentioned that earlier maybe we wouldn't be in this mess, now would we?
-tries to glare convincinly angrily at @BernieTheBernie, critical fails and just looks silly instead-
-
Now look at the first if clause: do you really need to check
value2
?Wait, do you think that if you have two variables both with generic type
T
, and you've determined that one of themis Foo
, the compiler should be able to infer that the other also definitelyis Foo
?It can't do that, because that's not actually true!
using System; interface Bla {} class Wibble : Bla {} class Wobble : Bla {} public class Program { static public void Main() { Bla arg1 = new Wibble(); Bla arg2 = new Wobble(); GenericMethod(arg1, arg2); } static public void GenericMethod<T>(T arg1, T arg2) { if (arg1 is Wibble) Console.WriteLine("arg1 is Wibble"); if (!(arg2 is Wibble)) Console.WriteLine("But arg2 is not Wibble!"); } }
The use of the word "the" here...
both
value1
andvalue2
have the same type.... seems like it captures the root of the fallacy. If "types" include interfaces or superclasses, then it's somewhat unsafe to talk about "the" type of an object, since an object can then have many types. Knowing the type of a variable it was assigned, or knowing a type for which an
is
check returned true, thus generally gives you only partial information about which concrete type the object has.
-
I have this weird feeling that the whole interface of whatever this is is horribly misdesigned, and the snippet in question is just a result of it.
-
@Cabbage The code snippet above is a verbatim copy, no line or function call in between left out. So, both value1 and value2 have the same type T. In this simple scenario, it is sufficient to check one value only.
-
@BernieTheBernie said in Value Types:
@Cabbage The code snippet above is a verbatim copy, no line or function call in between left out. So, both value1 and value2 have the same type T. In this simple scenario, it is sufficient to check one value only.
Without seeing the declarations of cameraParameterValue and _value, which your snippet does not supply, it is impossible to make that determination.
-
@BernieTheBernie said in Value Types:
@Cabbage The code snippet above is a verbatim copy, no line or function call in between left out. So, both value1 and value2 have the same type T. In this simple scenario, it is sufficient to check one value only.
As I read it, they have both been confirmed to be of some type which inherits from T. I do not know what the hierarchy leading to
double
is, or even whether C# uses the single tree or the forest paradigm here. Could it be thatT
isObject
,cameraParameterValue
isdouble
, and_value
isString
?
-
@TheCPUWizard said in Value Types:
@BernieTheBernie said in Value Types:
@Cabbage The code snippet above is a verbatim copy, no line or function call in between left out. So, both value1 and value2 have the same type T. In this simple scenario, it is sufficient to check one value only.
Without seeing the declarations of cameraParameterValue and _value, which your snippet does not supply, it is impossible to make that determination.
it is however sufficient to determine that the larger code from which this is snipped was spawned in the fetid mind of the elder god of chaos and discord, whose name we must not speak lest we summon them back to this plane to rend our minds and this world asunder.
-
@Vixen I don't remember @blakeyrat being this powerful.
-
-
@Vixen said in Value Types:
-tries to glare convincinly angrily at @BernieTheBernie, critical fails and just looks silly instead-
*boops the silly looking Vixen* don't mind the Bernie, he's just providing irrelevant context and laying down extra tracks to enhance derailment opportunities.
-
@Vixen said in Value Types:
he got better
-
@Tsaukpaetra said in Value Types:
@Vixen said in Value Types:
-tries to glare convincinly angrily at @BernieTheBernie, critical fails and just looks silly instead-
*boops the silly looking Vixen* don't mind the Bernie, he's just providing irrelevant context and laying down extra tracks to enhance derailment opportunities.
-
@BernieTheBernie said in Value Types:
@Cabbage The code snippet above is a verbatim copy, no line or function call in between left out. So, both value1 and value2 have the same type T. In this simple scenario, it is sufficient to check one value only.
Just to be clear,
double
has 8 types in its inheritance tree: 3 classes (including itself) and 5 interfaces. Just because value1 and value2 have the same typeT
does not mean thatT
isdouble
.
-
@powerlord said in Value Types:
@BernieTheBernie said in Value Types:
@Cabbage The code snippet above is a verbatim copy, no line or function call in between left out. So, both value1 and value2 have the same type T. In this simple scenario, it is sufficient to check one value only.
Just to be clear,
double
has 8 types in its inheritance tree: 3 classes (including itself) and 5 interfaces. Just because value1 and value2 have the same typeT
does not mean thatT
isdouble
.nor does it mean that they are actually the same type, let alone actually Type T. They both are Type T, but one or both may derive from subclasses of T
in example
class Animal { } class Mammal : Animal { } class Homonid: Mammal { } class Canid: Mammal { } class Human: Homonid { } class Fox: Canid { } class Powerlord: Human { } class Vixen: Fox { } static class Main { public static void Main() { Human powerlord = new Powerlord(); Fox vixen = new Vixen(); Animal offspring = BeastWithTwoBacks<Animal>(powerlord, vixen) } static T BeastWithTwoBacks<T>(T left, T, right) { // Footnote 1 /// left and right both derive from T but are not necessarily T }
1- Yes that was an excuse to make a sex joke
-
You can't derive from a double, nor can there be a
T
such thatConvert.ChangeType
results in a value that is adouble
. Well, of course, except whenT
isobject
, and the input value was adouble
to begin with (because if the target type isobject
it just returns the input value). So actually the original snippet was right(ish).
Although I would rather just testtypeof(T)==typeof(double) || typeof(T)==typeof(float)
, that's enough for this snippet, as far as I can tell.