How to Get the Data Type of a Variable in C#

How can I get the data type of a variable in C#?

Other answers offer good help with this question, but there is an important and subtle issue that none of them addresses directly. There are two ways of considering type in C#: static type and run-time type.

Static type is the type of a variable in your source code. It is therefore a compile-time concept. This is the type that you see in a tooltip when you hover over a variable or property in your development environment.

Run-time type is the type of an object in memory. It is therefore a run-time concept. This is the type returned by the GetType() method.

An object's run-time type is frequently different from the static type of the variable, property, or method that holds or returns it. For example, you can have code like this:

object o = "Some string";

The static type of the variable is object, but at run time, the type of the variable's referent is string. Therefore, the next line will print "System.String" to the console:

Console.WriteLine(o.GetType()); // prints System.String

But, if you hover over the variable o in your development environment, you'll see the type System.Object (or the equivalent object keyword).

For value-type variables, such as int, double, System.Guid, you know that the run-time type will always be the same as the static type, because value types cannot serve as the base class for another type; the value type is guaranteed to be the most-derived type in its inheritance chain. This is also true for sealed reference types: if the static type is a sealed reference type, the run-time value must either be an instance of that type or null.

Conversely, if the static type of the variable is an abstract type, then it is guaranteed that the static type and the runtime type will be different.

To illustrate that in code:

// int is a value type
int i = 0;
// Prints True for any value of i
Console.WriteLine(i.GetType() == typeof(int));

// string is a sealed reference type
string s = "Foo";
// Prints True for any value of s
Console.WriteLine(s == null || s.GetType() == typeof(string));

// object is an unsealed reference type
object o = new FileInfo("C:\\f.txt");
// Prints False, but could be true for some values of o
Console.WriteLine(o == null || o.GetType() == typeof(object));

// FileSystemInfo is an abstract type
FileSystemInfo fsi = new DirectoryInfo("C:\\");
// Prints False for all non-null values of fsi
Console.WriteLine(fsi == null || fsi.GetType() == typeof(FileSystemInfo));

Another user edited this answer to incorporate a function that appears below in the comments, a generic helper method to use type inference to get a reference to a variable's static type at run time, thanks to typeof:

Type GetStaticType<T>(T x) => typeof(T);

You can use this function in the example above:

Console.WriteLine(GetStaticType(o)); // prints System.Object

But this function is of limited utility unless you want to protect yourself against refactoring. When you are writing the call to GetStaticType, you already know that o's static type is object. You might as well write

Console.WriteLine(typeof(object)); // also prints System.Object!

This reminds me of some code I encountered when I started my current job, something like

SomeMethod("".GetType().Name);

instead of

SomeMethod("String");

Net Core: Find Data Type for any Variable Field in Class

Because the type is not known at compile time, you will not be able to use a strongly typed return type like Expression<Func<T,TKey>>.

public static class ExpressionTreesExtension {
static readonly Type funcTTResult = typeof(Func<,>);
public static IOrderedQueryable<T> OrderByProperty<T>(this IEnumerable<T> enumerable, string propertyName) {
var itemType = typeof(T);
var propertyInfo = itemType.GetProperty(propertyName);
var propertyType = propertyInfo.PropertyType;
// Func<T,TPropertyType>
var delegateType = funcTTResult.MakeGenericType(itemType, propertyType);
// T x =>
var parameterExpression = Expression.Parameter(itemType, "x");
// T x => x.Property
var propertyAccess = Expression.Property(parameterExpression, propertyInfo);
// Func<T,TPropertyType> = T x => x.Property
var keySelector = Expression.Lambda(delegateType, propertyAccess, parameterExpression);

var query = enumerable.AsQueryable();

// query.OrderBy(x => x.Property)
MethodCallExpression orderByExpression = Expression.Call(
typeof(Queryable),
"OrderBy",
new[] { query.ElementType, propertyInfo.PropertyType },
query.Expression, keySelector);

// Create an executable query from the expression tree.
return (IOrderedQueryable<T>)query.Provider.CreateQuery<T>(orderByExpression);
}
}

Reference How to: Use Expression Trees to Build Dynamic Queries (C#)

And used like

//IEnumerable<Person> records...
var data = records.OrderByProperty("Name");

How to get Values from variable of type Object in c#

You can use LINQ:

foreach (var item in eligibilityResult.Items.OfType<InquireSubscription>())
{
item.planId = ...;
}

This will ignore any Items that are not InquireSubscription or a subclass. Use Cast() if you want to be sure that it isn't the case:

foreach (var item in eligibilityResult.Items.Cast<InquireSubscription>())
{
item.planId = ...;
}

If you own the code of SubscriptionEligibility you should instead try to refactor it to not use object if possible

C# - Check datatype of a value via if condtion

You have two ways to check this:

string value = list.SelectedValue as string;

// The cast will return null if selectedvalue was not a string.
if( value == null ) return;

//Logic goes here.

If you just want to do the comparison:

if( list.SelectedValue is string )
{
// ...
}

How to check if variable's type matches Type stored in a variable

The other answers all contain significant omissions.

The is operator does not check if the runtime type of the operand is exactly the given type; rather, it checks to see if the runtime type is compatible with the given type:

class Animal {}
class Tiger : Animal {}
...
object x = new Tiger();
bool b1 = x is Tiger; // true
bool b2 = x is Animal; // true also! Every tiger is an animal.

But checking for type identity with reflection checks for identity, not for compatibility

bool b5 = x.GetType() == typeof(Tiger); // true
bool b6 = x.GetType() == typeof(Animal); // false! even though x is an animal

or with the type variable
bool b7 = t == typeof(Tiger); // true
bool b8 = t == typeof(Animal); // false! even though x is an animal

If that's not what you want, then you probably want IsAssignableFrom:

bool b9 = typeof(Tiger).IsAssignableFrom(x.GetType()); // true
bool b10 = typeof(Animal).IsAssignableFrom(x.GetType()); // true! A variable of type Animal may be assigned a Tiger.

or with the type variable
bool b11 = t.IsAssignableFrom(x.GetType()); // true
bool b12 = t.IsAssignableFrom(x.GetType()); // true! A

How to determine type of a variable? (not the type of the object)

Surprised this was so difficult, in the end I wrote this method, which seems to give the right answer.

public static class Extensions
{
public static Type GetVariableType<T>(this T instance)
{
return typeof(T);
}
}

Example usage:

void Main()
{
IList x = new List<int>{};
x.GetVariableType().Dump();
}

Prints System.Collections.IList

Get datatype from values passed as string

I've come up with the following solution which works:

enum dataType
{
System_Boolean = 0,
System_Int32 = 1,
System_Int64 = 2,
System_Double = 3,
System_DateTime = 4,
System_String = 5
}

private dataType ParseString(string str)
{

bool boolValue;
Int32 intValue;
Int64 bigintValue;
double doubleValue;
DateTime dateValue;

// Place checks higher in if-else statement to give higher priority to type.

if (bool.TryParse(str, out boolValue))
return dataType.System_Boolean;
else if (Int32.TryParse(str, out intValue))
return dataType.System_Int32;
else if (Int64.TryParse(str, out bigintValue))
return dataType.System_Int64;
else if (double.TryParse(str, out doubleValue))
return dataType.System_Double;
else if (DateTime.TryParse(str, out dateValue))
return dataType.System_DateTime;
else return dataType.System_String;

}

/// <summary>
/// Gets the datatype for the Datacolumn column
/// </summary>
/// <param name="column">Datacolumn to get datatype of</param>
/// <param name="dt">DataTable to get datatype from</param>
/// <param name="colSize">ref value to return size for string type</param>
/// <returns></returns>
public Type GetColumnType(DataColumn column, DataTable dt, ref int colSize)
{

Type T;
DataView dv = new DataView(dt);
//get smallest and largest values
string colName = column.ColumnName;

dv.RowFilter = "[" + colName + "] = MIN([" + colName + "])";
DataTable dtRange = dv.ToTable();
string strMinValue = dtRange.Rows[0][column.ColumnName].ToString();
int minValueLevel = (int)ParseString(strMinValue);

dv.RowFilter = "[" + colName + "] = MAX([" + colName + "])";
dtRange = dv.ToTable();
string strMaxValue = dtRange.Rows[0][column.ColumnName].ToString();
int maxValueLevel = (int)ParseString(strMaxValue);
colSize = strMaxValue.Length;

//get max typelevel of first n to 50 rows
int sampleSize = Math.Max(dt.Rows.Count, 50);
int maxLevel = Math.Max(minValueLevel, maxValueLevel);

for (int i = 0; i < sampleSize; i++)
{
maxLevel = Math.Max((int)ParseString(dt.Rows[i][column].ToString()), maxLevel);
}

string enumCheck = ((dataType)maxLevel).ToString();
T = Type.GetType(enumCheck.Replace('_', '.'));

//if typelevel = int32 check for bit only data & cast to bool
if (maxLevel == 1 && Convert.ToInt32(strMinValue) == 0 && Convert.ToInt32(strMaxValue) == 1)
{
T = Type.GetType("System.Boolean");
}

if (maxLevel != 5) colSize = -1;

return T;
}


Related Topics



Leave a reply



Submit