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
Measure a String Without Using a Graphics Object
Hot Unload/Reload of a Dll Used by an Application
How to "Zip" or "Rotate" a Variable Number of Lists
Fake-Scrolling Containers with Very Many Controls
Client Is Unauthorized to Retrieve Access Tokens Using This Method Gmail API C#
Delete Specific Line from a Text File
System.Web.Httpcontext.Current.User.Identity.Name VS System.Environment.Username in ASP.NET
How to Save Picturebox.Image to File
Sqldatasourceenumerator.Instance.Getdatasources() Does Not Locate Local SQL Server 2008 Instance
Implementing Hoey Shamos Algorithm with C#