I need to know how to convert an int to a nullable int. However, I keep getting an error "The binary operator Equal is not defined for the types 'System.Nullable`1[System.Int32]' and 'System.Int32'." Any solution. It needs to be Microsoft SQL Server's nullable int type.
somevalue = Expression.Constant(something.GetValue(some,null).To<Nullable<System.Int32>> ());
public static T To<T>(this object obj)
{
Type t = typeof(T);
Type u = Nullable.GetUnderlyingType(t);
if (u != null)
{
if (obj == null)
return default(T);
return (T)Convert.ChangeType(obj, u);
}
else
{
return (T)Convert.ChangeType(obj, t);
}
}'
Typically, you convert an int an int? using a cast.
int? myNullable = (int?) 15;
int myInt = (int) myNullable;
That To code seems to be you trying to construct a Constant of nullable type when given a value of non-nullable type but that is not at all the right way to go about this. The way you're trying to do this indicates that you have a misunderstanding about how boxed value types work.
That error message indicates that you are constructing a binary operator expression tree node which has as its operands an expression node of nullable int type and an expression node of int type. That's not legal; they have to be both nullable int. What you should be doing is wrapping the non-nullable int expression tree node in a Convert expression tree node which converts it to a nullable int, and then pass that to the binary operator expression tree node constructor.
That is, this is wrong:
var someIntExpr = Expression.Constant(123, typeof(int));
var someNubIntExpr = Expression.Constant(null, typeof(int?));
var badEq = Expression.Equal(someIntExpr, someNubIntExpr);
This is right:
var goodEq = Expression.Equal(Expression.Convert(someIntExpr, typeof(int?)), someNubIntExpr);
So why is what you're doing wrong?
You have a method To<T> which returns a T. It correctly takes in an int and returns the equivalent int?. So then what? You pass that to Expression.Constant, which boxes the nullable int into a boxed int, and then makes a constant out of that. You believe that there is such a thing as a boxed nullable value type, but there is not! A nullable value type boxes either to a null reference or to a boxed non-nullable value type.
So you could also solve your problem by not doing any of this crazy stuff in the first place. If you have a boxed int in hand, and you need a constant expression tree node of nullable type, just provide the type.
Expression.Constant(someBoxedIntValue, typeof(int?))
Done. So: wrapping up, you have two solutions:
If you have a boxed int in hand, pass it and the nullable value type you want to the Constant factory, or
if you have an expression node of type int in hand then use the Convert expression node factory, and pass it and the desired type to that.
Both will give you back an expression node of the correct type to be compared to another nullable int.
int test = 0; // set int
int? num = test; // convert test to a nullable int
num = null; // set num as null
int i = 1;
int? k;
k = i as int?;
Like this you will convert i which is an int to a nullable int ;)
int? is the short version of Nullable<int>.
Does something simpler like this not work?
int i;
int? temp = int.TryParse(<your value>, out i) ? (int?)i : null;
Here you go. A generic string to nullable primitive solution.
int? n = " 99 ".ToNullable<int>();
/// <summary>
/// Developed by Taylor Love
/// </summary>
public static class ToNullableStringExtension
{
/// <summary>
/// <para>More convenient than using T.TryParse(string, out T).
/// Works with primitive types, structs, and enums.
/// Tries to parse the string to an instance of the type specified.
/// If the input cannot be parsed, null will be returned.
/// </para>
/// <para>
/// If the value of the caller is null, null will be returned.
/// So if you have "string s = null;" and then you try "s.ToNullable...",
/// null will be returned. No null exception will be thrown.
/// </para>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="p_self"></param>
/// <returns></returns>
public static T? ToNullable<T>(this string p_self) where T : struct
{
if (!string.IsNullOrEmpty(p_self))
{
var converter = System.ComponentModel.TypeDescriptor.GetConverter(typeof(T));
if (converter.IsValid(p_self)) return (T)converter.ConvertFromString(p_self);
if (typeof(T).IsEnum) { T t; if (Enum.TryParse<T>(p_self, out t)) return t;}
}
return null;
}
https://github.com/Pangamma/PangammaUtilities-CSharp/tree/master/src/StringExtensions
Related
If I have an enum like so:
enum Beer
{
Bud = 10,
Stella = 20,
Unknown
}
Why does it not throw an exception when casting an int that is outside of these values to a type of Beer?
For example the following code doesn't throw an exception, it outputs '50' to the console:
int i = 50;
var b = (Beer) i;
Console.WriteLine(b.ToString());
I find this strange...can anyone clarify?
Taken from Confusion with parsing an Enum
This was a decision on the part of the people who created .NET. An enum is backed by another value type (int, short, byte, etc), and so it can actually have any value that is valid for those value types.
I personally am not a fan of the way this works, so I made a series of utility methods:
/// <summary>
/// Utility methods for enum values. This static type will fail to initialize
/// (throwing a <see cref="TypeInitializationException"/>) if
/// you try to provide a value that is not an enum.
/// </summary>
/// <typeparam name="T">An enum type. </typeparam>
public static class EnumUtil<T>
where T : struct, IConvertible // Try to get as much of a static check as we can.
{
// The .NET framework doesn't provide a compile-checked
// way to ensure that a type is an enum, so we have to check when the type
// is statically invoked.
static EnumUtil()
{
// Throw Exception on static initialization if the given type isn't an enum.
Require.That(typeof (T).IsEnum, () => typeof(T).FullName + " is not an enum type.");
}
/// <summary>
/// In the .NET Framework, objects can be cast to enum values which are not
/// defined for their type. This method provides a simple fail-fast check
/// that the enum value is defined, and creates a cast at the same time.
/// Cast the given value as the given enum type.
/// Throw an exception if the value is not defined for the given enum type.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="enumValue"></param>
/// <exception cref="InvalidCastException">
/// If the given value is not a defined value of the enum type.
/// </exception>
/// <returns></returns>
public static T DefinedCast(object enumValue)
{
if (!System.Enum.IsDefined(typeof(T), enumValue))
throw new InvalidCastException(enumValue + " is not a defined value for enum type " +
typeof (T).FullName);
return (T) enumValue;
}
/// <summary>
///
/// </summary>
/// <param name="enumValue"></param>
/// <returns></returns>
public static T Parse(string enumValue)
{
var parsedValue = (T)System.Enum.Parse(typeof (T), enumValue);
//Require that the parsed value is defined
Require.That(parsedValue.IsDefined(),
() => new ArgumentException(string.Format("{0} is not a defined value for enum type {1}",
enumValue, typeof(T).FullName)));
return parsedValue;
}
public static bool IsDefined(T enumValue)
{
return System.Enum.IsDefined(typeof (T), enumValue);
}
}
public static class EnumExtensions
{
public static bool IsDefined<T>(this T enumValue)
where T : struct, IConvertible
{
return EnumUtil<T>.IsDefined(enumValue);
}
}
This way, I can say:
if(!sEnum.IsDefined()) throw new Exception(...);
... or:
EnumUtil<Stooge>.Parse(s); // throws an exception if s is not a defined value.
Edit
Beyond the explanation given above, you have to realize that the .NET version of Enum follows a more C-inspired pattern than a Java-inspired one. This makes it possible to have "Bit Flag" enums which can use binary patterns to determine whether a particular "flag" is active in an enum value. If you had to define every possible combination of flags (i.e. MondayAndTuesday, MondayAndWednesdayAndThursday), these would be extremely tedious. So having the capacity to use undefined enum values can be really handy. It just requires a little extra work when you want a fail-fast behavior on enum types that don't leverage these sorts of tricks.
Enums are often used as flags:
[Flags]
enum Permission
{
None = 0x00,
Read = 0x01,
Write = 0x02,
}
...
Permission p = Permission.Read | Permission.Write;
The value of p is the integer 3, which is not a value of the enum, but clearly is a valid value.
I personally would rather have seen a different solution; I would rather have had the ability to make "bit array" integer types and "a set of distinct value" types as two different language features rather than conflating them both into "enum". But that's what the original language and framework designers came up with; as a result, we have to allow non-declared values of the enum to be legal values.
The short answer: The language designers decided to design the language this way.
The long answer: Section 6.2.2: Explicit enumeration conversions of the C# Language Specification says:
An explicit enumeration conversion between two types is processed by treating any participating enum-type as the underlying type of that enum-type, and then performing an implicit or explicit numeric conversion between the resulting types. For example, given an enum-type E with and underlying type of int, a conversion from E to byte is processed as an explicit numeric conversion (§6.2.1) from int to byte, and a conversion from byte to E is processed as an implicit numeric conversion (§6.1.2) from byte to int.
Basically, the enum is treated as the underlying type when it comes to do a conversion operation. By default, an enum's underlying type is Int32, which means the conversion is treated exactly like a conversion to Int32. This means any valid int value is allowable.
I suspect this was done mainly for performance reasons. By making enum a simple integral type and allowing any integral type conversion, the CLR doesn't need to do all of the extra checks. This means that using an enum doesn't really have any performance loss when compared to using an integer, which in turn helps encourage its use.
From the documentation:
A variable of type Days can be
assigned any value in the range of the
underlying type; the values are not
limited to the named constants.
I have a method with an out parameter that tries to do a type conversion. Basically:
public void GetParameterValue(out object destination)
{
object paramVal = "I want to return this. could be any type, not just string.";
destination = null; // default out param to null
destination = Convert.ChangeType(paramVal, destination.GetType());
}
The problem is that usually someone would call this like:
string output;
GetParameterValue(output);
This will fail because of:
destination.GetType()
destination is null, so we can't call .GetType() on it. We also can not call:
typeof(destination)
because destination is a variable name not a type name.
So is there any way to get the type of an object that is set to null? I would think there would have to be a way to know what type a storage location is without it being assigned anything.
Just to give a bit more info, I am trying to make a utility method that will grab the output parameters of an Oracle stored procedure. The issue is that DbParameter.Value is of type object.
What would be ideal would be for the developers to do something like:
string val = GetParameterValue("parameterName");
The notable thing is that there is no casting of types. In practice, you don't know the lparam of the "equals", so I went with:
string val;
GetParameterValue("parameterName", out val);
And figured within the method, I would know the destination type of the output variable. I guess that was a bad assumption. As an alternative, I also wrote the method:
public T GetParameterValue<T>(string paramName)
So the developers can do:
string val = GetParameterValue<string>("parameterName");
I find the explicit "string" declaration to be repetitive, especially since in practice, the destination if probably an object property and the oracle data type could change (think ORM):
MyObj.SomeProp = GetParameterValue<MyObj.SomeProp.GetType()>("parameterName");
But again, if MyObj.SomeProp is null, that .GetType() call fails. The VM has to know the type of MyObj.SomeProp, even when its null, right? or else how would it catch cast exceptions?
To partially solve my own problem, I can do:
MyObj.SomeProp = GetParameterValue<typeof(MyObj).GetField("SomeProp").GetType()>("parameterName");
The whole idea was to not have to explicitly use the Type in more than one place, so that if the data type changes, it only has to be changed in the destination object (MyObj.SomeProp) and in the DB. There has to be a better way...
So is there any way to get the type of an object that is set to null? I would think there would have to be a way to know what type a storage location is without it being assigned anything.
Not necessarily. The best that you can say is that it is an object. A null reference does not point to any storage location, so there is no metadata from which it can make that determination.
The best that you could do is change it to be more generic, as in:
public void GetParameterValue<T>(out T destination)
{
object paramVal = "Blah";
destination = default(T);
destination = Convert.ChangeType(paramVal, typeof(T));
}
The type of T can be inferred, so you shouldn't need to give a type parameter to the method explicitly.
It's possible if you don't mind declaring your method as a generic. Try this.
class Program
{
public static void GetParameterValue<T>(out T destination)
{
Console.WriteLine("typeof(T)=" + typeof(T).Name);
destination = default(T);
}
static void Main(string[] args)
{
string s;
GetParameterValue(out s);
int i;
GetParameterValue(out i);
}
}
The following extension method returns the type of its parameter as it was declared, regardless of its contents:
using System;
namespace MyNamespace
{
public static class Extensions
{
/// <summary>
/// Gets the declared type of the specified object.
/// </summary>
/// <typeparam name="T">The type of the object.</typeparam>
/// <param name="obj">The object.</param>
/// <returns>
/// A <see cref="Type"/> object representing type
/// <typeparamref name="T"/>; i.e., the type of <paramref name="obj"/>
/// as it was declared. Note that the contents of
/// <paramref name="obj"/> are irrelevant; if <paramref name="obj"/>
/// contains an object whose class is derived from
/// <typeparamref name="T"/>, then <typeparamref name="T"/> is
/// returned, not the derived type.
/// </returns>
public static Type GetDeclaredType<T>(
this T obj )
{
return typeof( T );
}
}
}
Since this is an extension method, its argument can be a null reference, and all of the following works OK:
string myString = "abc";
object myObj = myString;
Type myObjType = myObj.GetDeclaredType();
string myNullString = null;
object myNullObj = myNullString;
Type myNullObjType = myNullObj.GetDeclaredType();
Note that myObjType and myNullObjType will both be set to System.Object, not System.String.
If you actually want the type of obj's contents when it's not null, then change the return line to:
return (obj != null) ? obj.GetType() : typeof( T );
Currently, you have no way of knowing what gets passed into the method. You can convert it into a generic method like this:
public void GetParameterValue<T>(out T destination)
{
...
}
The type of your destination variable is always System.Object. You could just return
Convert.ChangeType(paramVal, System.Object).
#Rally25s:
string val;
GetParameterValue("parameterName", out val);
It's unclear from your message (in the answers) what the problem with that one was. If declared as:
void GetParameterValue<T>(string parameterName, out T val) { }
Than the call, as you wrote it above, will work (you don't need to specify the type). I'm guess that didn't work for you because you can't use a property as an "out" parameter. The way around that is to use both methods:
T GetParameterValue<T>(string parameterName, T ununsed) { }
This would be called like this:
MyObj.SomeProp = GetParameterValue("parameterName", MyObj.SomeProp);
which is rather kludgey, but not the worse method presented.
A different method, which I've used in C++, but haven't tried yet in C#, is to have GetParameterValue() some object of you own design, and then implement a number of implicit cast operators for it.
class ParameterHelper
{
private object value;
public ParameterHelper(object value) { this.value = value; }
public static implicit operator int(ParameterHelper v)
{ return (int) v.value; }
}
ParameterHelper GetParameterValue( string parameterName);
MyObj.SomeProp = GetParameterValue("parameterName");
I don't think it is possible to get the type when the value is null. Also, since you are calling inside GetParameterValue, the best you could do (when the value is null) is to get the type of the "destination" parameter which is "object". You might consider passing the Type as a parameter to GetParameterValue where you have more information, such as:
public void GetParameterValue(Type sourceType, out object destination) { //... }
If there is no instance, there is no instance type.
The best you can do is use the type of the reference, which means if you have an object reference (as in the method in the question), the reference type is object.
You probably shouldn't be trying to convert a null instance of one type into a null instance of another type...
In your example it would be null of type System.Object.
Does your example even compile? I get a "cannot convert from 'out string' to 'out object'" error.
At a theoretical level isn't a null really the same as a void pointer in C, which is to say that it holds a memory address and that's it? If so then it is similar to the case of a division by zero in Mathematics where the result is undefined.
One could do the following for this line:
string val = GetParameterValue<string>("parameterName");
Just remove that first string and now there isn't the repetition:
var val = GetParameterValue<string>("parameterName");
Not necessarily what you are looking for, though there is the question of how does one interpret null?
//**The working answer**
//**based on your discussion eheheheheeh**
public void s<T>(out T varName)
{
if (typeof (T) == typeof(HtmlTable))
{
//////////
}
}
protected void Page_Load(object sender, EventArgs e)
{
HtmlTable obj=null ;
s(out obj);
}
http://msdn.microsoft.com/en-us/library/58918ffs.aspx
or
private Hashtable propertyTable = new Hashtable();
public void LoadPropertyTypes()
{
Type t = this.GetType();
System.Reflection.MemberInfo[] memberInfo = t.GetMembers();
foreach (System.Reflection.MemberInfo mInfo in memberInfo)
{
string[] prop = mInfo.ToString().Split(Convert.ToChar(" "));
propertyTable.Add(prop[1], prop[0]);
}
}
public string GetMemberType(string propName)
{
if (propertyTable.ContainsKey(propName))
{
return Convert.ToString(propertyTable[propName]);
}
else{
return "N/A";
}
}
in that way we can use switch to manage different property types.
I have a little utility method that looks like so:
/// <summary>
/// Replaces a DBNull value with the default of the type specified
/// </summary>
/// <typeparam name="T">Resulting type</typeparam>
/// <param name="p_this">Object to check for DBNull</param>
/// <returns>p_this if it is not DBNull.Value, else default(T)</returns>
public static T ReplaceDBNullWithDefault<T>(this object p_this)
{
return p_this == System.DBNull.Value ? default(T) : (T)p_this;
}
In my specific scenario, I am taking a record out of a data table and taking a specific field out of it using weak types, and the specific field I'm getting is a long which is being boxed into an object. An example that reproduces this is as follows:
var obj = 2934L;
int num = obj.ReplaceDBNullWithDefault<int>();
It fails with an InvalidCastException, at (T)p_this.
I understand why, the boxed long cannot be cast directly to int, and trying to do it like this also fails:
object myLong = 234L;
int myInt = (int)myLong;
However, unboxing and then casting works fine:
object myLong = 234L;
int myInt = (int)(long)myLong;
How can I work around this in my method?
You can try this:
public static T ReplaceDBNullWithDefault<T>(this object p_this) where T : struct
{
return
p_this == System.DBNull.Value
? default(T)
: (T)Convert.ChangeType(p_this, typeof(T));
}
Nevertheless you will get an exception if you try to apply this function to a not-convertible type.
So probably it really would be better to cast the value manually to the known type.
You can use this approach:
/// <summary>
/// Replaces a DBNull value with the default of the type specified
/// </summary>
/// <typeparam name="T">Resulting type</typeparam>
/// <param name="value">Object to check for DBNull</param>
/// <param name="tryConvert">if true the object will be converted to the target type if possible, otherwise an InvalidCastException is raised</param>
/// <returns>p_this if it is not DBNull.Value, else default(T)</returns>
/// <exception cref="InvalidCastException">Thrown if the target type is incorrect and the value could not be converted to it</exception>
public static T ReplaceDbNullWithDefault<T>(this object value, bool tryConvert = true)
{
if (value == System.DBNull.Value || value == null)
return default(T);
if (value is T)
return (T) value;
if(!tryConvert || !(value is IConvertible))
throw new InvalidCastException($"Cannot convert {value.GetType()} to {typeof(T)}.");
return (T)((IConvertible) value).ToType(typeof(T), null);
}
I have a method with an out parameter that tries to do a type conversion. Basically:
public void GetParameterValue(out object destination)
{
object paramVal = "I want to return this. could be any type, not just string.";
destination = null; // default out param to null
destination = Convert.ChangeType(paramVal, destination.GetType());
}
The problem is that usually someone would call this like:
string output;
GetParameterValue(output);
This will fail because of:
destination.GetType()
destination is null, so we can't call .GetType() on it. We also can not call:
typeof(destination)
because destination is a variable name not a type name.
So is there any way to get the type of an object that is set to null? I would think there would have to be a way to know what type a storage location is without it being assigned anything.
Just to give a bit more info, I am trying to make a utility method that will grab the output parameters of an Oracle stored procedure. The issue is that DbParameter.Value is of type object.
What would be ideal would be for the developers to do something like:
string val = GetParameterValue("parameterName");
The notable thing is that there is no casting of types. In practice, you don't know the lparam of the "equals", so I went with:
string val;
GetParameterValue("parameterName", out val);
And figured within the method, I would know the destination type of the output variable. I guess that was a bad assumption. As an alternative, I also wrote the method:
public T GetParameterValue<T>(string paramName)
So the developers can do:
string val = GetParameterValue<string>("parameterName");
I find the explicit "string" declaration to be repetitive, especially since in practice, the destination if probably an object property and the oracle data type could change (think ORM):
MyObj.SomeProp = GetParameterValue<MyObj.SomeProp.GetType()>("parameterName");
But again, if MyObj.SomeProp is null, that .GetType() call fails. The VM has to know the type of MyObj.SomeProp, even when its null, right? or else how would it catch cast exceptions?
To partially solve my own problem, I can do:
MyObj.SomeProp = GetParameterValue<typeof(MyObj).GetField("SomeProp").GetType()>("parameterName");
The whole idea was to not have to explicitly use the Type in more than one place, so that if the data type changes, it only has to be changed in the destination object (MyObj.SomeProp) and in the DB. There has to be a better way...
So is there any way to get the type of an object that is set to null? I would think there would have to be a way to know what type a storage location is without it being assigned anything.
Not necessarily. The best that you can say is that it is an object. A null reference does not point to any storage location, so there is no metadata from which it can make that determination.
The best that you could do is change it to be more generic, as in:
public void GetParameterValue<T>(out T destination)
{
object paramVal = "Blah";
destination = default(T);
destination = Convert.ChangeType(paramVal, typeof(T));
}
The type of T can be inferred, so you shouldn't need to give a type parameter to the method explicitly.
It's possible if you don't mind declaring your method as a generic. Try this.
class Program
{
public static void GetParameterValue<T>(out T destination)
{
Console.WriteLine("typeof(T)=" + typeof(T).Name);
destination = default(T);
}
static void Main(string[] args)
{
string s;
GetParameterValue(out s);
int i;
GetParameterValue(out i);
}
}
The following extension method returns the type of its parameter as it was declared, regardless of its contents:
using System;
namespace MyNamespace
{
public static class Extensions
{
/// <summary>
/// Gets the declared type of the specified object.
/// </summary>
/// <typeparam name="T">The type of the object.</typeparam>
/// <param name="obj">The object.</param>
/// <returns>
/// A <see cref="Type"/> object representing type
/// <typeparamref name="T"/>; i.e., the type of <paramref name="obj"/>
/// as it was declared. Note that the contents of
/// <paramref name="obj"/> are irrelevant; if <paramref name="obj"/>
/// contains an object whose class is derived from
/// <typeparamref name="T"/>, then <typeparamref name="T"/> is
/// returned, not the derived type.
/// </returns>
public static Type GetDeclaredType<T>(
this T obj )
{
return typeof( T );
}
}
}
Since this is an extension method, its argument can be a null reference, and all of the following works OK:
string myString = "abc";
object myObj = myString;
Type myObjType = myObj.GetDeclaredType();
string myNullString = null;
object myNullObj = myNullString;
Type myNullObjType = myNullObj.GetDeclaredType();
Note that myObjType and myNullObjType will both be set to System.Object, not System.String.
If you actually want the type of obj's contents when it's not null, then change the return line to:
return (obj != null) ? obj.GetType() : typeof( T );
Currently, you have no way of knowing what gets passed into the method. You can convert it into a generic method like this:
public void GetParameterValue<T>(out T destination)
{
...
}
The type of your destination variable is always System.Object. You could just return
Convert.ChangeType(paramVal, System.Object).
#Rally25s:
string val;
GetParameterValue("parameterName", out val);
It's unclear from your message (in the answers) what the problem with that one was. If declared as:
void GetParameterValue<T>(string parameterName, out T val) { }
Than the call, as you wrote it above, will work (you don't need to specify the type). I'm guess that didn't work for you because you can't use a property as an "out" parameter. The way around that is to use both methods:
T GetParameterValue<T>(string parameterName, T ununsed) { }
This would be called like this:
MyObj.SomeProp = GetParameterValue("parameterName", MyObj.SomeProp);
which is rather kludgey, but not the worse method presented.
A different method, which I've used in C++, but haven't tried yet in C#, is to have GetParameterValue() some object of you own design, and then implement a number of implicit cast operators for it.
class ParameterHelper
{
private object value;
public ParameterHelper(object value) { this.value = value; }
public static implicit operator int(ParameterHelper v)
{ return (int) v.value; }
}
ParameterHelper GetParameterValue( string parameterName);
MyObj.SomeProp = GetParameterValue("parameterName");
I don't think it is possible to get the type when the value is null. Also, since you are calling inside GetParameterValue, the best you could do (when the value is null) is to get the type of the "destination" parameter which is "object". You might consider passing the Type as a parameter to GetParameterValue where you have more information, such as:
public void GetParameterValue(Type sourceType, out object destination) { //... }
If there is no instance, there is no instance type.
The best you can do is use the type of the reference, which means if you have an object reference (as in the method in the question), the reference type is object.
You probably shouldn't be trying to convert a null instance of one type into a null instance of another type...
In your example it would be null of type System.Object.
Does your example even compile? I get a "cannot convert from 'out string' to 'out object'" error.
At a theoretical level isn't a null really the same as a void pointer in C, which is to say that it holds a memory address and that's it? If so then it is similar to the case of a division by zero in Mathematics where the result is undefined.
One could do the following for this line:
string val = GetParameterValue<string>("parameterName");
Just remove that first string and now there isn't the repetition:
var val = GetParameterValue<string>("parameterName");
Not necessarily what you are looking for, though there is the question of how does one interpret null?
//**The working answer**
//**based on your discussion eheheheheeh**
public void s<T>(out T varName)
{
if (typeof (T) == typeof(HtmlTable))
{
//////////
}
}
protected void Page_Load(object sender, EventArgs e)
{
HtmlTable obj=null ;
s(out obj);
}
http://msdn.microsoft.com/en-us/library/58918ffs.aspx
or
private Hashtable propertyTable = new Hashtable();
public void LoadPropertyTypes()
{
Type t = this.GetType();
System.Reflection.MemberInfo[] memberInfo = t.GetMembers();
foreach (System.Reflection.MemberInfo mInfo in memberInfo)
{
string[] prop = mInfo.ToString().Split(Convert.ToChar(" "));
propertyTable.Add(prop[1], prop[0]);
}
}
public string GetMemberType(string propName)
{
if (propertyTable.ContainsKey(propName))
{
return Convert.ToString(propertyTable[propName]);
}
else{
return "N/A";
}
}
in that way we can use switch to manage different property types.
why is typeof int? an Int32
int? x = 1;
Console.WriteLine(x.GetType().Name);
If it is okay then what's the use of Nullable.GetUnderlyingType?
Calling GetType() boxes your variable. The CLR has a special rule that Nullable<T> gets boxed to T. So x.GetType will return Int32 instead of Nullable<Int32>.
int? x = 1;
x.GetType() //Int32
typeof(int?) //Nullable<Int32>
Since a Nullable containing null will be boxed to null the following will throw an exception:
int? x = null;
x.GetType() //throws NullReferenceException
To quote MSDN on Boxing Nullable Types:
Objects based on nullable types are only boxed if the object is non-null. If HasValue is false, the object reference is assigned to null instead of boxing
If the object is non-null -- if HasValue is true -- then boxing occurs, but only the underlying type that the nullable object is based on is boxed. Boxing a non-null nullable value type boxes the value type itself, not the System.Nullable<T> that wraps the value type.
This example is a bit confused, because:
int? x = 1;
creates a Nullable<int> like you expect; however:
Type type = x.GetType();
is a call to a non-virtual method on object, which isn't (and can't be) overridden - therefore this is a boxing operation; and Nullable<T> has special boxing rules:
if it is empty, it boxes to null
if it has a value, the value is boxed and returned
i.e.
int? x = 1;
int y = 1;
box to exactly the same thing.
Therefore, you are passing typeof(int) to GetUnderlyingType.
A more illustrative example of when this helps is when using reflection:
class Foo {
public int? Bar {get;set;}
}
...
Type type = typeof(Foo); // usually indirectly
foreach(var prop in type.GetProperties()) {
Type propType = prop.PropertyType,
nullType = Nullable.GetUnderlyingType(propType);
if(nullType != null) {
// special code for handling Nullable<T> properties;
// note nullType now holds the T
} else {
// code for handling other properties
}
}
Its for when you don't know its Int32.
Example:
public Type GetNullableUnderlyingType<T>(Nullable<T> obj)
where T : struct
{
return Nullable.GetUnderlyingType(typeof(Nullable<T>));
}
Here, you can pass any Nullable object and get it to return it's underlying type.
When you write int? it's as if you've written Nullable<int>. That's the type you're looking for, I think.
Mainly its for dealing with a generic method::
e.g.
public static void SomeMethod<T>(T argument)
{
if(Nullable.GetUnderlyingType(typeof(T) != null)
{
/* special case for nullable code go here */
}
else
{
/* Do something else T isn't nullable */
}
}
It's important to know this, as certain things that are very cheap can be wildly expensive on nullable's. For instance, if(argument == null) is normally super cheap, but when done in a generic method on a Nullable<T> is forced to box the argument to get a null reference. Your best bet is to use EqualityComparer<T>.Default which will slow everything else down, but makes nullable's not suffer.