简体   繁体   中英

Get the type from a nullable variable

public class MyType
{
    public int? MyId { get; set; }    
}

MyType myType = new MyType();
myType.MyId.GetType()

the last line returns an exception since MyId is not set (ie. it's null). How I get the type ( int? or even int ) in this case? Note, int? is used as an example, the variable may have any type, this is just a simplified example.

Note, according to Microsoft, this is supposed to work:

int? a = 17;
Type typeOfA = a.GetType();
Console.WriteLine(typeOfA.FullName);
// Output:
// System.Int32

and it does work when the value is assigned...

EDIT.

Looking at some of the replies and comments, I would like to add that in code, I pass myType.MyId as an object to a method that needs to figure out its type. Basically it looks similar to:

public void RunQuery(string sql, List<(string parameterName, object parameterValue)> parameters)

so myType.MyId is passed into RunQuery as parameterValue

You can use reflection to get declared type of a property (which is known at compile time):

Type t = typeof(MyType).GetProperty(nameof(MyType.MyId)).PropertyType;

And GetType() is used to figure out the actual type of an object in runtime, but that does not make sense for a null reference.

Edit:

When you cast Nullable<T> to an Object , its value is boxed, so, if it was null , you will get just an Object variable with null reference, and you won't be able to find out the type any more.

So, you should somehow change your infrastructure to make the type be passed with your parameter. The fastest workaround is to pass it explicitly

List<(string parameterName, object parameterValue, Type parameterType)> parameters

Check out System.Data.SqlClient.SqlParameter , I am not sure, but this is probably exactly what you need to use.

[Edited], I've re-written my solution to address your question: Making a function that is agnostic to MyType:

string GetPropertyName<T>(T prop)
{
    var type = typeof(T);
    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
    {
        return type.GenericTypeArguments[0].FullName;
    }
    else
    {
        return type.FullName;
    }
}

You can now call it like this:

MyType myType = new MyType();
string name = GetPropertyName(myType.MyId);
Console.WriteLine(name);  // Outputs System.Int32

I've test it, and it's working for me.

BTW, if you pass it a non-nullable member, it will return that property name. You can test that for yourself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM