This question already has an answer here:
这个问题在这里已有答案:
- .NET : How do you get the Type of a null object? 12 answers
.NET:如何获得null对象的Type? 12个答案
I have the C# method
我有C#方法
private static string TypeNameLower(object o)
{
return o.GetType().Name.ToLower();
}
to give me the lower case type name of the input object.
给我输入对象的小写类型名称。
But if input is a string set to null or a nullable int set to null then this method of course fails.
但是如果input是一个设置为null的字符串或一个设置为null的nullable int,那么这个方法当然会失败。
How do I get the type name in this situation?
在这种情况下如何获取类型名称?
11 个解决方案
#1
Jeff is correct. That's like asking what kind of cake would have been in an empty box with no label.
杰夫是对的。这就像问一个没有标签的空盒子里会有什么样的蛋糕。
As an alternative to Fortran's answer you could also do:
作为Fortran答案的替代方案,您还可以:
string TypeNameLower<T>(T obj) {
return typeof(T).Name.ToLower(CultureInfo.InvariantCulture);
}
string TypeNameLower(object obj) {
if (obj != null) { return obj.GetType().Name.ToLower(CultureInfo.InvariantCulture); }
else { return null; }
}
string s = null;
TypeNameLower(s); // goes to the generic version
That way, C# will pick the generic one at compile time if it knows enough about the type you're passing in.
这样,如果C#足够了解你传入的类型,它将在编译时选择泛型。
#2
I thought I'd post my answer, even though this question is old, because in my opinion, the accepted answer is wrong. That answer was pretty creative, so I don't mean to knock it. And for all I know, it could be what the OP really wanted.
我以为我会发布我的答案,即使这个问题已经过时了,因为在我看来,接受的答案是错误的。那个答案很有创意,所以我不是故意要敲门。据我所知,这可能是OP真正想要的。
But, as you'll see from my examples below, I think that in almost all cases, the idea of using the generic function described in the accepted answer is either (A) unnecessary or (B) flat-out wrong. I've copied the generic function I'm talking about from the accepted answer and pasted it below for reference:
但是,正如您将从下面的示例中看到的那样,我认为在几乎所有情况下,使用接受答案中描述的通用函数的想法是(A)不必要或(B)完全错误。我已经从接受的答案中复制了我正在谈论的通用函数,并将其粘贴在下面以供参考:
string TypeNameLower<T>(T obj) {
return typeof(T).Name.ToLower();
}
Now, let's see some ways this function might be used:
现在,让我们看看可以使用此函数的一些方法:
Examples where the Generic Function is Unnecessary:
通用功能不必要的示例:
var s = "hello";
var t = TypeNameLower(s);
//or
foreach(char c in "banana")
WriteLine(TypeNameLower(c));
//or
foreach(MyCustomStruct x in listOfMyCustomStruct)
WriteLine(TypeNameLower(x));
In these examples the function works--that is, it does return the correct values which are "string", "char", and "mycustomstruct", respectively. However in all cases like these, (i.e. where the generic function actually does return the correct type), the compiler knows ahead of time what the defined type of the variable is, and so does the programmer, of course (unless they got confused about their variable names). So the function is completely unnecessary, and the programmer may as well have done this:
在这些示例中,函数有效 - 也就是说,它确实返回正确的值,分别是“string”,“char”和“mycustomstruct”。但是在所有这些情况下(即泛型函数确实返回正确的类型),编译器会提前知道变量的定义类型是什么,当然程序员也是如此(除非他们对此感到困惑)他们的变量名称)。所以函数是完全没必要的,程序员也可以这样做:
var s = "hello";
var t = "string";
//or
foreach(char c in "banana")
WriteLine("char");
//or
foreach(MyCustomStruct x in listOfMyCustomStruct)
WriteLine("mycustomstruct");
That might seem naive at first, but think about it for a while...it might take a while for it to really sink in...Try to come up with ANY scenario where using the generic function provides accurate information at Runtime that isn't already known (and hence could be auto-generated by the compiler or code-generation utilities such as T4 templates) at compile-time.
起初这可能看起来很幼稚,但考虑一下......它可能需要一段时间才真正陷入其中......尝试提出任何使用泛型函数在运行时提供准确信息的场景在编译时已经知道(因此可以由编译器或代码生成实用程序(如T4模板)自动生成)。
Now the point of the previous set of examples was just to demonstrate a minor annoyance with the generic function--that it is unnecessary in every case where it returns the correct result. But more importantly, take a look at the examples below. They demonstrates that in any other case, the result of the generic function is actually wrong if you expect the function to return the name of the true runtime type of the object. The function is actually only guaranteed to return the name of a type that the true value is assignable to, which might be an ancestor class, an interface, or "object" itself.
现在,上一组示例的目的只是为了证明泛型函数的一个小麻烦 - 在每种情况下它都不需要返回正确的结果。但更重要的是,请看下面的示例。他们演示了在任何其他情况下,如果您希望函数返回对象的真实运行时类型的名称,则泛型函数的结果实际上是错误的。实际上,该函数仅保证返回真值可分配的类型的名称,该类型可能是祖先类,接口或“对象”本身。
Examples where the Generic Function is Wrong
通用功能错误的示例
Stream ms = new MemoryStream();
IEnumerable str = "Hello";
IComparable i = 23;
object j = 1;
TypeNameLower(ms); //returns "stream" instead of "memorystream"
TypeNameLower(str); //returns "ienumerable" instead of "string"
TypeNameLower(i); //returns "icomparable" instead of "int32"
TypeNameLower(j); //returns "object" instead of "int32"
TypeNameLower<object>(true); //returns "object" instead of "bool"
In all cases, the results are quite wrong as you can see. Now, I admit that the last two lines were a bit contrived to demonstrate the point (not to mention that TypeNameLower(j)
would actually be compiled to use the non-generic version of the function that is also part of the accepted answer--but you get the idea...)
在所有情况下,结果都是错误的,你可以看到。现在,我承认最后两行有点人为了证明这一点(更不用说TypeNameLower(j)实际上会被编译为使用函数的非泛型版本,这也是已接受答案的一部分 - 但你明白了......)
The problem is that the function actually ignores the type of the object being passed in, and only uses the (compile-time) information of the generic parameter type to return the value.
问题是该函数实际上忽略了传入的对象的类型,并且仅使用泛型参数类型的(编译时)信息来返回该值。
A better implementation would be as follows:
更好的实施方式如下:
string TypeNameLower<T>(T obj) {
Type t;
if (obj == null)
t = typeof(T);
else
t = obj.GetType();
return t.Name.ToLower();
}
Now the function returns the name of the true runtime type whenever the object is non-null, and it defaults to the compile-time/defined type when the type is null
.
现在,只要对象为非null,函数就会返回真实运行时类型的名称,当类型为null时,它默认为编译时/定义类型。
Importantly, this function could be used WITHOUT a non-generic version!! The result would be that the function would never return null
. The most general return value would be "object" e.g:
重要的是,这个功能可以在没有非通用版本的情况下使用!!结果是函数永远不会返回null。最常见的返回值是“对象”,例如:
object x = null;
string s = null;
byte[] b = null;
MyClass m = null;
TypeNameLower(x); // returns "object"
TypeNameLower(s); // returns "string"
TypeNameLower(b); // returns "byte[]"
TypeNameLower(m); // returns "myclass"
Note that this is actually more consistent with the defined objective of the function, as requested by the OP. That is, if the OP really does want to find out what the type-name of the object was if it weren't null, then returning null would NEVER be an appropriate answer, because null ISN'T the name of any Type, and typeof(null) isn't defined.
请注意,这实际上与OP所要求的功能的定义目标更加一致。也就是说,如果OP确实想要找出对象的类型名称是什么,如果它不是null,那么返回null将永远不是一个合适的答案,因为null不是任何Type的名称,并且typeof(null)未定义。
Every variable in C# descends from System.Object
, so by definition, if the value weren't null
then it would be an Object
and that is in many cases the most that can be determined about a null reference at runtime.
C#中的每个变量都来自System.Object,因此根据定义,如果值不为null,那么它将是一个Object,并且在许多情况下,在运行时可以确定关于空引用的最多值。
#3
// Uses the compiler's type inference mechanisms for generics to find out the type
// 'self' was declared with in the current scope.
static public Type GetDeclaredType<TSelf>(TSelf self)
{
return typeof(TSelf);
}
void Main()
{
// ...
Foo bar;
bar = null;
Type myType = GetDeclaredType(bar);
Console.Write(myType.Name);
}
Prints:
Foo
I posted this also at a similar topic, I hope it's of any use for you. ;-)
我也发布了类似的主题,我希望它对你有用。 ;-)
#4
if (o == null) return "null";
else return o.GetType().Name.ToLower();
simple solution for a simple problem :-p
解决一个简单问题的简单方法:-p
#5
As others mention, you can't. This is actually a well-known issue with languages that allow pure null references to objects. One way to work around it is to use the "Null Object pattern". The basic idea is that instead of using null
for empty references, you assign to it an instance of a "do nothing" object. For example:
正如其他人所说,你做不到。对于允许对对象进行纯空引用的语言,这实际上是一个众所周知的问题。解决它的一种方法是使用“空对象模式”。基本思想是,不为空引用使用null,而是为其分配“不执行任何”对象的实例。例如:
public class Circle
{
public virtual float Radius { get; set; }
public Circle(float radius)
{
Radius = radius;
}
}
public class NullCircle : Circle
{
public override float Radius
{
get { return float.NaN; }
set { }
}
public NullCircle() { }
}
You can then pass an instance of NullCircle
instead of null
and you will be able to test its type like in your code.
然后,您可以传递NullCircle的实例而不是null,并且您将能够像在代码中一样测试其类型。
#6
To the best of my knowledge you can't. Null indicates the absence of a value and is not distinct for different types.
据我所知,你做不到。 Null表示缺少值,并且对于不同类型不明显。
#7
There is no notion that a null string is different than a null Array is different than a null anything else. From inside your function, you cannot determine the type name.
没有任何概念认为空字符串不同于null数组不同于null其他任何东西。从函数内部,您无法确定类型名称。
More specifically, an instance of a reference class (internally) includes a "pointer" to the type information about the object. When the input is null, there is no such pointer so the type information does not exist.
更具体地,引用类的实例(内部)包括关于对象的类型信息的“指针”。当输入为null时,没有这样的指针,因此类型信息不存在。
#8
Just expanding upon @Josh Einstein's answer.
只是扩展@Josh爱因斯坦的答案。
Below are two extension methods to get the type of a variable even if it is currently set to null.
下面是获取变量类型的两种扩展方法,即使它当前设置为null。
/// <summary>
/// Gets an object's type even if it is null.
/// </summary>
/// <typeparam name="T">The type of the object.</typeparam>
/// <param name="that">The object being extended.</param>
/// <returns>The objects type.</returns>
public static Type GetTheType<T>(this T that)
{
return typeof(T);
}
/// <summary>
/// Gets an object's type even if it is null.
/// </summary>
/// <param name="that">The object being extended.</param>
/// <returns>The objects type.</returns>
public static Type GetTheType(this object that)
{
if (that != null)
{
return that.GetType();
}
return null;
}
Also, here are two simple unit tests to test the extension methods.
此外,这里有两个简单的单元测试来测试扩展方法。
/// <summary>
/// Tests to make sure that the correct type is return.
/// </summary>
[Test(Description = "Tests to make sure that the correct type is return.")]
public void Test_GetTheType()
{
var value = string.Empty;
var theType = value.GetTheType();
Assert.That(theType, Is.SameAs(typeof(string)));
}
/// <summary>
/// Tests to make sure that the correct type is returned even if the value is null.
/// </summary>
[Test(Description = "Tests to make sure that the correct type is returned even if the value is null.")]
public void Test_GetTheType_ReturnsTypeEvenIfValueIsNull()
{
string value = null;
var theType = value.GetTheType();
Assert.That(theType, Is.SameAs(typeof(string)));
}
Edit Sorry, I forgot to mention that I was needing this exact same feature for a project I'm currently on. All credit still should go to @Josh Einstein :D
编辑抱歉,我忘了提到我需要这个完全相同的功能,我目前正在进行的项目。所有的功劳仍然归于@Josh Einstein:D
#9
It is very frustrating that C# does not allow for such a determination to be made. And it is not akin to asking what cake you would have in an empty box - an object comprises two independent components - the "incarnation" of the object and the information on the class that was used to create the object. The fact that this information can't be accessed easily is an ommission on the part of the C#'s developers.
令人非常沮丧的是,C#不允许做出这样的决定。并且它不等于在空盒子中询问你会有什么蛋糕 - 一个对象包含两个独立的组件 - 对象的“化身”和用于创建对象的类的信息。无法轻易访问此信息这一事实是C#开发人员的一个优点。
All you can do by way of determination is this rather crippling method:
你可以通过决心做的就是这种相当严重的方法:
void Method(object obj)
{
if(obj is int)
{
//obj is of the int type
}
else if(obj is SomeComplexType)
{
//obj is of the SomeComplexType type
}
}
So, you can see that even if the object is null, its type information is nevertheless travelling alongside the object, it is not lost, you just cant handily access it. But this is, to say the least, inconvenient.
所以,你可以看到,即使对象为null,它的类型信息仍然与对象一起移动,它不会丢失,你只是不能轻易地访问它。但至少可以说,这是不方便的。
#10
If you have an object by itself (let's say as an input parameter to a method with type object), with no definition or generic type, there is no way to find the type. The reason is simple, you cannot send message to (invoke any method on) the object to ask about the type.
如果你有一个对象(让我们说作为一个带有类型对象的方法的输入参数),没有定义或泛型类型,就没有办法找到这个类型。原因很简单,你不能发送消息(调用任何方法)对象询问类型。
There could be some other workarounds, as you see in some answers, like using generic types. In that case, you're not asking the Null object, you are asking the generic type for its type.
可能会有一些其他的解决方法,正如您在一些答案中看到的那样,例如使用泛型类型。在这种情况下,您不是在询问Null对象,而是询问泛型类型。
#11
Consider this code:
考虑以下代码:
public class MyClass1{}
public class MyClass2{}
public static void Test1()
{
MyClass1 one = null;
MyClass2 two = (MyClass2) (object) one;
one = new MyClass1();
//invalid cast exception
two = (MyClass2)(object) one;
}
The runtime-type of a null instance is object
, at least from a type-safety point of view.
null实例的运行时类型是object,至少从类型安全的角度来看。
#1
Jeff is correct. That's like asking what kind of cake would have been in an empty box with no label.
杰夫是对的。这就像问一个没有标签的空盒子里会有什么样的蛋糕。
As an alternative to Fortran's answer you could also do:
作为Fortran答案的替代方案,您还可以:
string TypeNameLower<T>(T obj) {
return typeof(T).Name.ToLower(CultureInfo.InvariantCulture);
}
string TypeNameLower(object obj) {
if (obj != null) { return obj.GetType().Name.ToLower(CultureInfo.InvariantCulture); }
else { return null; }
}
string s = null;
TypeNameLower(s); // goes to the generic version
That way, C# will pick the generic one at compile time if it knows enough about the type you're passing in.
这样,如果C#足够了解你传入的类型,它将在编译时选择泛型。
#2
I thought I'd post my answer, even though this question is old, because in my opinion, the accepted answer is wrong. That answer was pretty creative, so I don't mean to knock it. And for all I know, it could be what the OP really wanted.
我以为我会发布我的答案,即使这个问题已经过时了,因为在我看来,接受的答案是错误的。那个答案很有创意,所以我不是故意要敲门。据我所知,这可能是OP真正想要的。
But, as you'll see from my examples below, I think that in almost all cases, the idea of using the generic function described in the accepted answer is either (A) unnecessary or (B) flat-out wrong. I've copied the generic function I'm talking about from the accepted answer and pasted it below for reference:
但是,正如您将从下面的示例中看到的那样,我认为在几乎所有情况下,使用接受答案中描述的通用函数的想法是(A)不必要或(B)完全错误。我已经从接受的答案中复制了我正在谈论的通用函数,并将其粘贴在下面以供参考:
string TypeNameLower<T>(T obj) {
return typeof(T).Name.ToLower();
}
Now, let's see some ways this function might be used:
现在,让我们看看可以使用此函数的一些方法:
Examples where the Generic Function is Unnecessary:
通用功能不必要的示例:
var s = "hello";
var t = TypeNameLower(s);
//or
foreach(char c in "banana")
WriteLine(TypeNameLower(c));
//or
foreach(MyCustomStruct x in listOfMyCustomStruct)
WriteLine(TypeNameLower(x));
In these examples the function works--that is, it does return the correct values which are "string", "char", and "mycustomstruct", respectively. However in all cases like these, (i.e. where the generic function actually does return the correct type), the compiler knows ahead of time what the defined type of the variable is, and so does the programmer, of course (unless they got confused about their variable names). So the function is completely unnecessary, and the programmer may as well have done this:
在这些示例中,函数有效 - 也就是说,它确实返回正确的值,分别是“string”,“char”和“mycustomstruct”。但是在所有这些情况下(即泛型函数确实返回正确的类型),编译器会提前知道变量的定义类型是什么,当然程序员也是如此(除非他们对此感到困惑)他们的变量名称)。所以函数是完全没必要的,程序员也可以这样做:
var s = "hello";
var t = "string";
//or
foreach(char c in "banana")
WriteLine("char");
//or
foreach(MyCustomStruct x in listOfMyCustomStruct)
WriteLine("mycustomstruct");
That might seem naive at first, but think about it for a while...it might take a while for it to really sink in...Try to come up with ANY scenario where using the generic function provides accurate information at Runtime that isn't already known (and hence could be auto-generated by the compiler or code-generation utilities such as T4 templates) at compile-time.
起初这可能看起来很幼稚,但考虑一下......它可能需要一段时间才真正陷入其中......尝试提出任何使用泛型函数在运行时提供准确信息的场景在编译时已经知道(因此可以由编译器或代码生成实用程序(如T4模板)自动生成)。
Now the point of the previous set of examples was just to demonstrate a minor annoyance with the generic function--that it is unnecessary in every case where it returns the correct result. But more importantly, take a look at the examples below. They demonstrates that in any other case, the result of the generic function is actually wrong if you expect the function to return the name of the true runtime type of the object. The function is actually only guaranteed to return the name of a type that the true value is assignable to, which might be an ancestor class, an interface, or "object" itself.
现在,上一组示例的目的只是为了证明泛型函数的一个小麻烦 - 在每种情况下它都不需要返回正确的结果。但更重要的是,请看下面的示例。他们演示了在任何其他情况下,如果您希望函数返回对象的真实运行时类型的名称,则泛型函数的结果实际上是错误的。实际上,该函数仅保证返回真值可分配的类型的名称,该类型可能是祖先类,接口或“对象”本身。
Examples where the Generic Function is Wrong
通用功能错误的示例
Stream ms = new MemoryStream();
IEnumerable str = "Hello";
IComparable i = 23;
object j = 1;
TypeNameLower(ms); //returns "stream" instead of "memorystream"
TypeNameLower(str); //returns "ienumerable" instead of "string"
TypeNameLower(i); //returns "icomparable" instead of "int32"
TypeNameLower(j); //returns "object" instead of "int32"
TypeNameLower<object>(true); //returns "object" instead of "bool"
In all cases, the results are quite wrong as you can see. Now, I admit that the last two lines were a bit contrived to demonstrate the point (not to mention that TypeNameLower(j)
would actually be compiled to use the non-generic version of the function that is also part of the accepted answer--but you get the idea...)
在所有情况下,结果都是错误的,你可以看到。现在,我承认最后两行有点人为了证明这一点(更不用说TypeNameLower(j)实际上会被编译为使用函数的非泛型版本,这也是已接受答案的一部分 - 但你明白了......)
The problem is that the function actually ignores the type of the object being passed in, and only uses the (compile-time) information of the generic parameter type to return the value.
问题是该函数实际上忽略了传入的对象的类型,并且仅使用泛型参数类型的(编译时)信息来返回该值。
A better implementation would be as follows:
更好的实施方式如下:
string TypeNameLower<T>(T obj) {
Type t;
if (obj == null)
t = typeof(T);
else
t = obj.GetType();
return t.Name.ToLower();
}
Now the function returns the name of the true runtime type whenever the object is non-null, and it defaults to the compile-time/defined type when the type is null
.
现在,只要对象为非null,函数就会返回真实运行时类型的名称,当类型为null时,它默认为编译时/定义类型。
Importantly, this function could be used WITHOUT a non-generic version!! The result would be that the function would never return null
. The most general return value would be "object" e.g:
重要的是,这个功能可以在没有非通用版本的情况下使用!!结果是函数永远不会返回null。最常见的返回值是“对象”,例如:
object x = null;
string s = null;
byte[] b = null;
MyClass m = null;
TypeNameLower(x); // returns "object"
TypeNameLower(s); // returns "string"
TypeNameLower(b); // returns "byte[]"
TypeNameLower(m); // returns "myclass"
Note that this is actually more consistent with the defined objective of the function, as requested by the OP. That is, if the OP really does want to find out what the type-name of the object was if it weren't null, then returning null would NEVER be an appropriate answer, because null ISN'T the name of any Type, and typeof(null) isn't defined.
请注意,这实际上与OP所要求的功能的定义目标更加一致。也就是说,如果OP确实想要找出对象的类型名称是什么,如果它不是null,那么返回null将永远不是一个合适的答案,因为null不是任何Type的名称,并且typeof(null)未定义。
Every variable in C# descends from System.Object
, so by definition, if the value weren't null
then it would be an Object
and that is in many cases the most that can be determined about a null reference at runtime.
C#中的每个变量都来自System.Object,因此根据定义,如果值不为null,那么它将是一个Object,并且在许多情况下,在运行时可以确定关于空引用的最多值。
#3
// Uses the compiler's type inference mechanisms for generics to find out the type
// 'self' was declared with in the current scope.
static public Type GetDeclaredType<TSelf>(TSelf self)
{
return typeof(TSelf);
}
void Main()
{
// ...
Foo bar;
bar = null;
Type myType = GetDeclaredType(bar);
Console.Write(myType.Name);
}
Prints:
Foo
I posted this also at a similar topic, I hope it's of any use for you. ;-)
我也发布了类似的主题,我希望它对你有用。 ;-)
#4
if (o == null) return "null";
else return o.GetType().Name.ToLower();
simple solution for a simple problem :-p
解决一个简单问题的简单方法:-p
#5
As others mention, you can't. This is actually a well-known issue with languages that allow pure null references to objects. One way to work around it is to use the "Null Object pattern". The basic idea is that instead of using null
for empty references, you assign to it an instance of a "do nothing" object. For example:
正如其他人所说,你做不到。对于允许对对象进行纯空引用的语言,这实际上是一个众所周知的问题。解决它的一种方法是使用“空对象模式”。基本思想是,不为空引用使用null,而是为其分配“不执行任何”对象的实例。例如:
public class Circle
{
public virtual float Radius { get; set; }
public Circle(float radius)
{
Radius = radius;
}
}
public class NullCircle : Circle
{
public override float Radius
{
get { return float.NaN; }
set { }
}
public NullCircle() { }
}
You can then pass an instance of NullCircle
instead of null
and you will be able to test its type like in your code.
然后,您可以传递NullCircle的实例而不是null,并且您将能够像在代码中一样测试其类型。
#6
To the best of my knowledge you can't. Null indicates the absence of a value and is not distinct for different types.
据我所知,你做不到。 Null表示缺少值,并且对于不同类型不明显。
#7
There is no notion that a null string is different than a null Array is different than a null anything else. From inside your function, you cannot determine the type name.
没有任何概念认为空字符串不同于null数组不同于null其他任何东西。从函数内部,您无法确定类型名称。
More specifically, an instance of a reference class (internally) includes a "pointer" to the type information about the object. When the input is null, there is no such pointer so the type information does not exist.
更具体地,引用类的实例(内部)包括关于对象的类型信息的“指针”。当输入为null时,没有这样的指针,因此类型信息不存在。
#8
Just expanding upon @Josh Einstein's answer.
只是扩展@Josh爱因斯坦的答案。
Below are two extension methods to get the type of a variable even if it is currently set to null.
下面是获取变量类型的两种扩展方法,即使它当前设置为null。
/// <summary>
/// Gets an object's type even if it is null.
/// </summary>
/// <typeparam name="T">The type of the object.</typeparam>
/// <param name="that">The object being extended.</param>
/// <returns>The objects type.</returns>
public static Type GetTheType<T>(this T that)
{
return typeof(T);
}
/// <summary>
/// Gets an object's type even if it is null.
/// </summary>
/// <param name="that">The object being extended.</param>
/// <returns>The objects type.</returns>
public static Type GetTheType(this object that)
{
if (that != null)
{
return that.GetType();
}
return null;
}
Also, here are two simple unit tests to test the extension methods.
此外,这里有两个简单的单元测试来测试扩展方法。
/// <summary>
/// Tests to make sure that the correct type is return.
/// </summary>
[Test(Description = "Tests to make sure that the correct type is return.")]
public void Test_GetTheType()
{
var value = string.Empty;
var theType = value.GetTheType();
Assert.That(theType, Is.SameAs(typeof(string)));
}
/// <summary>
/// Tests to make sure that the correct type is returned even if the value is null.
/// </summary>
[Test(Description = "Tests to make sure that the correct type is returned even if the value is null.")]
public void Test_GetTheType_ReturnsTypeEvenIfValueIsNull()
{
string value = null;
var theType = value.GetTheType();
Assert.That(theType, Is.SameAs(typeof(string)));
}
Edit Sorry, I forgot to mention that I was needing this exact same feature for a project I'm currently on. All credit still should go to @Josh Einstein :D
编辑抱歉,我忘了提到我需要这个完全相同的功能,我目前正在进行的项目。所有的功劳仍然归于@Josh Einstein:D
#9
It is very frustrating that C# does not allow for such a determination to be made. And it is not akin to asking what cake you would have in an empty box - an object comprises two independent components - the "incarnation" of the object and the information on the class that was used to create the object. The fact that this information can't be accessed easily is an ommission on the part of the C#'s developers.
令人非常沮丧的是,C#不允许做出这样的决定。并且它不等于在空盒子中询问你会有什么蛋糕 - 一个对象包含两个独立的组件 - 对象的“化身”和用于创建对象的类的信息。无法轻易访问此信息这一事实是C#开发人员的一个优点。
All you can do by way of determination is this rather crippling method:
你可以通过决心做的就是这种相当严重的方法:
void Method(object obj)
{
if(obj is int)
{
//obj is of the int type
}
else if(obj is SomeComplexType)
{
//obj is of the SomeComplexType type
}
}
So, you can see that even if the object is null, its type information is nevertheless travelling alongside the object, it is not lost, you just cant handily access it. But this is, to say the least, inconvenient.
所以,你可以看到,即使对象为null,它的类型信息仍然与对象一起移动,它不会丢失,你只是不能轻易地访问它。但至少可以说,这是不方便的。
#10
If you have an object by itself (let's say as an input parameter to a method with type object), with no definition or generic type, there is no way to find the type. The reason is simple, you cannot send message to (invoke any method on) the object to ask about the type.
如果你有一个对象(让我们说作为一个带有类型对象的方法的输入参数),没有定义或泛型类型,就没有办法找到这个类型。原因很简单,你不能发送消息(调用任何方法)对象询问类型。
There could be some other workarounds, as you see in some answers, like using generic types. In that case, you're not asking the Null object, you are asking the generic type for its type.
可能会有一些其他的解决方法,正如您在一些答案中看到的那样,例如使用泛型类型。在这种情况下,您不是在询问Null对象,而是询问泛型类型。
#11
Consider this code:
考虑以下代码:
public class MyClass1{}
public class MyClass2{}
public static void Test1()
{
MyClass1 one = null;
MyClass2 two = (MyClass2) (object) one;
one = new MyClass1();
//invalid cast exception
two = (MyClass2)(object) one;
}
The runtime-type of a null instance is object
, at least from a type-safety point of view.
null实例的运行时类型是object,至少从类型安全的角度来看。