如何在 C# 中获取对象的小写名称,即使为 null

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/930147/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 03:26:57  来源:igfitidea点击:

How to get the lowercase name of an object, even when null, in C#

c#

提问by

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 的可空 int ,那么这个方法当然会失败。

How do I get the type name in this situation?

在这种情况下如何获取类型名称?

采纳答案by Josh

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# 对你传入的类型有足够的了解,它就会在编译时选择泛型的。

回答by Jeff Foster

To the best of my knowledge you can't. Null indicates the absence of a value and is not distinct for different types.

据我所知,你不能。Null 表示没有值并且对于不同的类型没有区别。

回答by fortran

if (o == null) return "null";
else return o.GetType().Name.ToLower();

simple solution for a simple problem :-p

一个简单问题的简单解决方案:-p

回答by DocMax

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.

没有任何概念认为空字符串不同于空数组不同于其他任何东西。从您的函数内部,您无法确定类型名称。

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.

更具体地说,引用类的实例(在内部)包括一个指向关于对象的类型信息的“指针”。当输入为空时,没有这样的指针,所以类型信息不存在。

回答by Hans Van Slooten

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 nullfor 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 NullCircleinstead of nulland you will be able to test its type like in your code.

然后你可以传递一个NullCircle而不是的实例,null你将能够像在你的代码中一样测试它的类型。

回答by Amy B

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.

object至少从类型安全的角度来看,空实例的运行时类型是。

回答by Alex

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.

所以,你可以看到,即使对象为空,它的类型信息仍然伴随着对象传播,它没有丢失,你只是不能方便地访问它。但这至少可以说是不方便的。

回答by Amin Emami

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 对象,而是在询问泛型类型的类型。

回答by herzmeister

// 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. ;-)

我也在一个类似的主题上发布了这个,我希望它对你有用。;-)

回答by Tanner Watson

Just expanding upon @Josh Einstein's answer.

只是扩展@Jos​​h Einstein 的回答。

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)));
    }

EditSorry, 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