Is there a generic unbox function like in f#? - c#

I m trying to use object handlers and I have this working fine to put stuff in memory. But when I look up the object again I return:
object(object[,])
or
object(double[,])
how do I unbox this in c#?
object(double[,]) boxedobj = ....
double[,] unboxedobj = unbox(boxedobj);
Ideally I would like to do this in a generic way so that it doesnt matter whether the tybe is double[] or double[,] or object[,], etc

The F# unbox function is pretty much just doing cast to any other type that you specify. In C#, this could be written like this:
static R Unbox<R>(object anything) {
return (R)anything;
}
So in your case with double[,] you'd need something like:
var array = (double[,])boxed;
In most cases unbox<'R> anything would just translate to casting using (R)anything. The only case where this does not work is when you are in another generic method and you are casting between two generic types. In that case, you need to go to object first (to make sure that the value is boxed):
static R Unbox<R, T>(T anything) {
return (R)(object)anything;
}

Unless I'm missing your point, casting to/from object should automatically box/unbox value types for you (an array is not a value type, BTW):
double d = 0.0; // not boxed
object obj = d; // boxed
double d2 = (double)obj; // unboxed
The bigger question is - why do you care if its boxed or not?

Related

What is the difference between these two casting methods? [duplicate]

Consider the following code:
void Handler(object o, EventArgs e)
{
// I swear o is a string
string s = (string)o; // 1
//-OR-
string s = o as string; // 2
// -OR-
string s = o.ToString(); // 3
}
What is the difference between the three types of casting (okay, the 3rd one is not a casting, but you get the intent). Which one should be preferred?
string s = (string)o; // 1
Throws InvalidCastException if o is not a string. Otherwise, assigns o to s, even if o is null.
string s = o as string; // 2
Assigns null to s if o is not a string or if o is null. For this reason, you cannot use it with value types (the operator could never return null in that case). Otherwise, assigns o to s.
string s = o.ToString(); // 3
Causes a NullReferenceException if o is null. Assigns whatever o.ToString() returns to s, no matter what type o is.
Use 1 for most conversions - it's simple and straightforward. I tend to almost never use 2 since if something is not the right type, I usually expect an exception to occur. I have only seen a need for this return-null type of functionality with badly designed libraries which use error codes (e.g. return null = error, instead of using exceptions).
3 is not a cast and is just a method invocation. Use it for when you need the string representation of a non-string object.
string s = (string)o; Use when something should
definitely be the other thing.
string s = o as string; Use when something might be the other
thing.
string s = o.ToString(); Use when you don't care what
it is but you just want to use the
available string representation.
It really depends on whether you know if o is a string and what you want to do with it. If your comment means that o really really is a string, I'd prefer the straight (string)o cast - it's unlikely to fail.
The biggest advantage of using the straight cast is that when it fails, you get an InvalidCastException, which tells you pretty much what went wrong.
With the as operator, if o isn't a string, s is set to null, which is handy if you're unsure and want to test s:
string s = o as string;
if ( s == null )
{
// well that's not good!
gotoPlanB();
}
However, if you don't perform that test, you'll use s later and have a NullReferenceException thrown. These tend to be more common and a lot harder to track down once they happens out in the wild, as nearly every line dereferences a variable and may throw one. On the other hand, if you're trying to cast to a value type (any primitive, or structs such as DateTime), you have to use the straight cast - the as won't work.
In the special case of converting to a string, every object has a ToString, so your third method may be okay if o isn't null and you think the ToString method might do what you want.
'as' is based on 'is', which is a keyword that checks at runtime if the object is polimorphycally compatible (basically if a cast can be made) and returns null if the check fails.
These two are equivalent:
Using 'as':
string s = o as string;
Using 'is':
if(o is string)
s = o;
else
s = null;
On the contrary, the c-style cast is made also at runtime, but throws an exception if the cast cannot be made.
Just to add an important fact:
The 'as' keyword only works with reference types. You cannot do:
// I swear i is an int
int number = i as int;
In those cases you have to use casting.
If you already know what type it can cast to, use a C-style cast:
var o = (string) iKnowThisIsAString;
Note that only with a C-style cast can you perform explicit type coercion.
If you don't know whether it's the desired type and you're going to use it if it is, use as keyword:
var s = o as string;
if (s != null) return s.Replace("_","-");
//or for early return:
if (s==null) return;
Note that as will not call any type conversion operators. It will only be non-null if the object is not null and natively of the specified type.
Use ToString() to get a human-readable string representation of any object, even if it can't cast to string.
The as keyword is good in asp.net when you use the FindControl method.
Hyperlink link = this.FindControl("linkid") as Hyperlink;
if (link != null)
{
...
}
This means you can operate on the typed variable rather then having to then cast it from object like you would with a direct cast:
object linkObj = this.FindControl("linkid");
if (link != null)
{
Hyperlink link = (Hyperlink)linkObj;
}
It's not a huge thing, but it saves lines of code and variable assignment, plus it's more readable
According to experiments run on this page: http://www.dotnetguru2.org/sebastienros/index.php/2006/02/24/cast_vs_as
(this page is having some "illegal referrer" errors show up sometimes, so just refresh if it does)
Conclusion is, the "as" operator is normally faster than a cast. Sometimes by many times faster, sometimes just barely faster.
I peronsonally thing "as" is also more readable.
So, since it is both faster and "safer" (wont throw exception), and possibly easier to read, I recommend using "as" all the time.
2 is useful for casting to a derived type.
Suppose a is an Animal:
b = a as Badger;
c = a as Cow;
if (b != null)
b.EatSnails();
else if (c != null)
c.EatGrass();
will get a fed with a minimum of casts.
"(string)o" will result in an InvalidCastException as there's no direct cast.
"o as string" will result in s being a null reference, rather than an exception being thrown.
"o.ToString()" isn't a cast of any sort per-se, it's a method that's implemented by object, and thus in one way or another, by every class in .net that "does something" with the instance of the class it's called on and returns a string.
Don't forget that for converting to string, there's also Convert.ToString(someType instanceOfThatType) where someType is one of a set of types, essentially the frameworks base types.
It seems the two of them are conceptually different.
Direct Casting
Types don't have to be strictly related. It comes in all types of flavors.
Custom implicit/explicit casting: Usually a new object is created.
Value Type Implicit: Copy without losing information.
Value Type Explicit: Copy and information might be lost.
IS-A relationship: Change reference type, otherwise throws exception.
Same type: 'Casting is redundant'.
It feels like the object is going to be converted into something else.
AS operator
Types have a direct relationship. As in:
Reference Types: IS-A relationship Objects are always the same, just the reference changes.
Value Types: Copy boxing and nullable types.
It feels like the you are going to handle the object in a different way.
Samples and IL
class TypeA
{
public int value;
}
class TypeB
{
public int number;
public static explicit operator TypeB(TypeA v)
{
return new TypeB() { number = v.value };
}
}
class TypeC : TypeB { }
interface IFoo { }
class TypeD : TypeA, IFoo { }
void Run()
{
TypeA customTypeA = new TypeD() { value = 10 };
long longValue = long.MaxValue;
int intValue = int.MaxValue;
// Casting
TypeB typeB = (TypeB)customTypeA; // custom explicit casting -- IL: call class ConsoleApp1.Program/TypeB ConsoleApp1.Program/TypeB::op_Explicit(class ConsoleApp1.Program/TypeA)
IFoo foo = (IFoo)customTypeA; // is-a reference -- IL: castclass ConsoleApp1.Program/IFoo
int loseValue = (int)longValue; // explicit -- IL: conv.i4
long dontLose = intValue; // implict -- IL: conv.i8
// AS
int? wraps = intValue as int?; // nullable wrapper -- IL: call instance void valuetype [System.Runtime]System.Nullable`1<int32>::.ctor(!0)
object o1 = intValue as object; // box -- IL: box [System.Runtime]System.Int32
TypeD d1 = customTypeA as TypeD; // reference conversion -- IL: isinst ConsoleApp1.Program/TypeD
IFoo f1 = customTypeA as IFoo; // reference conversion -- IL: isinst ConsoleApp1.Program/IFoo
//TypeC d = customTypeA as TypeC; // wouldn't compile
}
All given answers are good, if i might add something:
To directly use string's methods and properties (e.g. ToLower) you can't write:
(string)o.ToLower(); // won't compile
you can only write:
((string)o).ToLower();
but you could write instead:
(o as string).ToLower();
The as option is more readable (at least to my opinion).
string s = o as string; // 2
Is prefered, as it avoids the performance penalty of double casting.
I would like to attract attention to the following specifics of the as operator:
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/as
Note that the as operator performs only reference conversions,
nullable conversions, and boxing conversions. The as operator can't
perform other conversions, such as user-defined conversions, which
should instead be performed by using cast expressions.
Use direct cast string s = (string) o; if in the logical context of your app string is the only valid type. With this approach, you will get InvalidCastException and implement the principle of Fail-fast. Your logic will be protected from passing the invalid type further or get NullReferenceException if used as operator.
If the logic expects several different types cast string s = o as string; and check it on null or use is operator.
New cool feature have appeared in C# 7.0 to simplify cast and check is a Pattern matching:
if(o is string s)
{
// Use string variable s
}
or
switch (o)
{
case int i:
// Use int variable i
break;
case string s:
// Use string variable s
break;
}
When trying to get the string representation of anything (of any type) that could potentially be null, I prefer the below line of code. It's compact, it invokes ToString(), and it correctly handles nulls. If o is null, s will contain String.Empty.
String s = String.Concat(o);
Since nobody mentioned it, the closest to instanceOf to Java by keyword is this:
obj.GetType().IsInstanceOfType(otherObj)

Function is being called with type in front of it: (T)func(param1, param2). What is this called and what is it for?

Function is being called with type in front of it: (T)func(param1, param2). What is this called and what is it for? I'd assume it's coercing a return type?
Again, the pattern takes the form:
(T)func(params)
example:
(int)Mathf.Log(level, 2f) // it's an example from unity, level is of type int
The (T) is an explicit cast. See the docs here, under the "Explicit Conversions" title: https://msdn.microsoft.com/en-us/library/ms173105.aspx
The func(params) bit is just a method call. The cast is not part of it, you're just casting the result.
// cast the result of a method call
var i = (int)Mathf.Log(level, 2f);
// cast a random object
var s = (string)someObject;
It's not a pattern per se (depending on what exactly you mean by "pattern")... it's just C#. It sounds like maybe you're confused by the fact that it appears a method is being converted to a primitive type?
What it's actually doing is converting the return type of Mathf.Log (a float) to an int.
So this:
int log = (int)Mathf.Log(level, 2f);
Is equivalent to this:
float result = Mathf.Log(level, 2f);
int log = (int)result;
It's simply a cast ; Math.Log returns a double so a cast is needed to make it an int (truncating the result)

Difference between Casting, Parsing and Converting [duplicate]

This question already has answers here:
Is casting the same thing as converting?
(11 answers)
Closed 9 years ago.
I have been working on some code for a while. And I had a question: What's the difference among casting, parsing and converting? And when we can use them?
Casting is when you take a variable of one type and change it to a different type. You can only do that in some cases, like so:
string str = "Hello";
object o = str;
string str2 = (string)o; // <-- This is casting
Casting does not change the variable's value - the value remains of the same type (the string "Hello").
Converting is when you take a value from one type and convert it to a different type:
double d = 5.5;
int i = (int)d; // <---- d was converted to an integer
Note that in this case, the conversion was done in the form of casting.
Parsing is taking a string and converting it to a different type by understanding its content. For instance, converting the string "123" to the number 123, or the string "Saturday, September 22nd" to a DateTime.
Casting: Telling the compiler that an object is really something else without changing it (though some data loss may be incurred).
object obj_s= "12345";
string str_i = (string) obj; // "12345" as string, explicit
int small = 12345;
long big = 0;
big = small; // 12345 as long, implicit
Parsing: Telling the program to interpret (on runtime) a string.
string int_s = "12345";
int i = int.Parse(int_s); // 12345 as int
Converting: Telling the program to use built in methods to try to change type for what may be not simply interchangeable.
double dub = 123.45;
int i = System.Convert.ToInt32(dub); // 123 as int
These are three terms each with specific uses:
casting - changing one type to another. In order to do this, the
types must be compatible: int -> object; IList<T> -> IEnumerable<T>
parsing - typically refers to reading strings and extracting useful parts
converting - similar to casting, but typically a conversion would involve changing one type to an otherwise non-compatible type. An example of that would be converting objects to strings.
A cast from one type to another requires some form of compatibility, usually via inheritance or implementation of an interface. Casting can be implicit or explicit:
class Foo : IFoo {
// implementations
}
// implicit cast
public IFoo GetFoo() {
return Foo;
}
// explicit cast
public IFoo GetFoo() {
return Foo as IFoo;
}
There are quite a few ways to parse. We read about XML parsing; some types have Parse and TryParse methods; and then there are times we need to parse strings or other types to extract the 'stuff we care about'.
int.Parse("3") // returns an integer value of 3
int.TryParse("foo", out intVal) // return true if the string could be parsed; otherwise false
Converting may entail changing one type into another incompatible one. This could involve some parsing as well. Conversion examples would usually be, IMO, very much tied to specific contexts.
casting
(casting to work the types need to be compatible)
Converting between data types can be done explicitly using a cast
static void _Casting()
{
int i = 10;
float f = 0;
f = i; // An implicit conversion, no data will be lost.
f = 0.5F;
i = (int)f; // An explicit conversion. Information will be lost.
}
parsing (Parsing is conversion between different types:)
converts one type to another type can be called as parsing uisng int.parse
int num = int.Parse("500");
traversing through data items like XML can be also called as parsing
When user-defined conversions get involved, this usually entails returning a different object/value. user-defined conversions usually exist between value types rather than reference types, so this is rarely an issue.
converting
Using the Convert-class actually just helps you parse it
for more please refer http://msdn.microsoft.com/en-us/library/ms228360%28VS.80%29.aspx
This question is actually pretty complicated...
Normally, a cast just tells the runtime to change one type to another. These have to be types that are compatible. For example an int can always be represented as a long so it is OK to cast it to a long. Some casts have side-effects. For example, a float will drop its precision if it is cast to an int. So (int)1.5f will result in int value 1. Casts are usually the fastest way to change the type, because it is a single IL operator. For example, the code:
public void CastExample()
{
int i = 7;
long l = (long)i;
}
Performs the cast by running the IL code:
conv.i8 //convert to 8-byte integer (a.k.a. Int64, a.k.a. long).
A parse is some function that takes in once type and returns another. It is an actual code function, not just an IL operator. This usually takes longer to run, because it runs multiple lines of code.
For example, this code:
public void ParseExample()
{
string s = "7";
long l = long.Parse(s);
}
Runs the IL code:
call int64 [mscorlib]System.Int64::Parse(string)
In other words it calls an actual method. Internally, the Int64 type provides that method:
public static long Parse(String s) {
return Number.ParseInt64(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo);
}
And Number.Parse:
[System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static Int64 ParseInt64(String value, NumberStyles options, NumberFormatInfo numfmt) {
Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
Int64 i = 0;
StringToNumber(value, options, ref number, numfmt, false);
if ((options & NumberStyles.AllowHexSpecifier) != 0) {
if (!HexNumberToInt64(ref number, ref i)) {
throw new OverflowException(Environment.GetResourceString("Overflow_Int64"));
}
}
else {
if (!NumberToInt64(ref number, ref i)) {
throw new OverflowException(Environment.GetResourceString("Overflow_Int64"));
}
}
return i;
}
And so on... so you can see it is actually doing a lot of code.
Now where things get more complicated is that although a cast is usually the fastest, classes can override the implicit and explicit cast operators. For example, if I write the class:
public class CastableClass
{
public int IntValue { get; set; }
public static explicit operator int(CastableClass castable)
{
return castable.IntValue;
}
}
I have overridden the explicit cast operator for int, so I can now do:
public void OverridedCastExample()
{
CastableClass cc = new CastableClass {IntValue = 7};
int i = (int)cc;
}
Which looks like a normal cast, but in actuality it calls my method that I defined on my class. The IL code is:
call int32 UnitTestProject1.CastableClass::op_Explicit(class UnitTestProject1.CastableClass)
So anyway, you typically want to cast whenever you can. Then parse if you can't.
Casting: or Parsing
A cast explicitly invokes the conversion operator from one type to another.
Casting variables is not simple. A complicated set of rules resolves casts. In some cases data is lost and the cast cannot be reversed. In others an exception is provoked in the execution engine.
int.Parse is a simplest method but it throws exceptions on invalid input.
TryParse
int.TryParse is one of the most useful methods for parsing integers in the C# language. This method works the same way as int.Parse.
int.TryParse has try and catch structure inside. So, it does not throw exceptions
Convert:
Converts a base data type to another base data type.
Convert.ToInt32, along with its siblings Convert.ToInt16 and Convert.ToInt64, is actually a static wrapper method for the int.Parse method.
Using TryParse instead of Convert or Cast is recommended by many programmers.
source:www.dotnetperls.com
Different people use it to mean different things. It need not be true outside .net world, but here is what I have understood in .net context reading Eric Lippert's blogs:
All transformations of types from one form to another can be called conversion. One way of categorizing may be
implicit -
a. representation changing (also called coercion)
int i = 0;
double d = i;
object o = i; // (specifically called boxing conversion)
IConvertible o = i; // (specifically called boxing conversion)
Requires implicit conversion operator, conversion always succeeds (implicit conversion operator should never throw), changes the referential identity of the object being converted.
b. representation preserving (also called implicit reference conversion)
string s = "";
object o = s;
IList<string> l = new List<string>();
Only valid for reference types, never changes the referential identity of the object being converted, conversion always succeeds, guaranteed at compile time, no runtime checks.
explicit (also called casting) -
a. representation changing
int i = 0;
enum e = (enum)i;
object o = i;
i = (int)o; // (specifically called unboxing conversion)
Requires explicit conversion operator, changes the referential identity of the object being converted, conversion may or may not succeed, does runtime check for compatibility.
b. representation preserving (also called explicit reference conversion)
object o = "";
string s = (string)o;
Only valid for reference types, never changes the referential identity of the object being converted, conversion may or may not succeed, does runtime check for compatibility.
While conversions are language level constructs, Parse is a vastly different thing in the sense it's framework level, or in other words they are custom methods written to get an output from an input, like int.Parse which takes in a string and returns an int.

params object[] method parameters boxed?

Ok, so when I have a method that looks like
getPacket(params object[] inputs)
{
}
Is the inputs array an array of boxed variables or is it simply just an array of the original types (im sending multiple different types tho, eg. short, int, bool)
If they are boxed can you do run-time unboxing to the original type without knowing the original type?
If they aren't boxed, how can I tell whether it's an int, short, bool etc. as I want to be able to make a single method that puts together a byte array from a whole stack of different types.
Another question, are the objects in the array in the same order as they were passed in the method invocation?
The objects in the array will be in the same order that they were passed to the method and they will be boxed if the source parameter is a value type.
You can use the is keyword to check the underlying type of each object and act accordingly, for example:
static void Main(string[] args)
{
Receive(1, true);
}
static void Receive(params object[] values)
{
foreach (var v in values)
{
if (v is int)
{
// ...
}
else if (v is bool)
{
// ...
}
}
}
if you have an array of objects, then yes, if for example you put integers in the array, they will be boxed. I dont know of any unboxing methods without knowing the actual types involved, so you will have to cast the items in the array to whatever value they actually represent.

see what type is a dynamic variable c#

how can I test if a dynamic variable is a double for example?
I need to do something like:
void someMethod(dynamic var1)
{
if(var1.isDouble)
{...
}else if(var1 is int)
// do something else....
}
That approach is fine (i.e. var1 is double), though that's usually not what dynamic is meant to accomplish. More often, you should dynamic when you do know what the type will be, but it's difficult or impossible to show that at compile-time (e.g. a COM interop scenario, a ViewBag in MVC, etc.) You could just use object if you want to pass a variable of unknown type. Otherwise, the run-time will do the type analysis for you during execution, which can be a big performance hit if that's not what you need.
In general, there could be scenarios where you'd want to use dynamic as a catch-all container, but this doesn't appear to be one of them. In this case, why not have a number of method overloads that each take the desired type:
void someMethod(double d) { ... }
void someMethod(int i) { ... }
This scenario has nothing to do with dynamic keyword as explained by dlev.
Did you mean:
void someMethod(object o)
{
if (o is double) {
double d = (double)o;
// do something with d
} else if (o is int) {
int i = (int)o;
// do something with i
}
}
Either way, this is generally a bad practice unless absolutely needed.
What are you trying to accomplish?
shouldn't this work:
if(var1 is Double)
You can check whether the type is implicitly convertible to double, with the is keyword:
if (var1 is double)

Categories

Resources