简体   繁体   English

一种干净的方式来转换为对象的实际类型

[英]A clean way to cast to an objects actual type

What I'm doing is looking up a value for a particular field in the hashtable. 我正在做的是查找哈希表中特定字段的值。 The object can be a handful of primitive types who's value is destined to be put inside XML but it comes out of the hashtable as an object. 该对象可以是少数原始类型,它们的值注定要放在XML中,但它来自哈希表作为对象。 So I have the problem of needing to decide what the type is, cast it up and then use that types ToString. 所以我有需要决定类型是什么的问题,将其抛出然后使用ToString类型。 It would be nice if I didn't need to cast it but then it will call the ToString on the object type and not the counterpart method on the actual type. 如果我不需要强制转换它会很好但是它会调用对象类型的ToString而不是实际类型的对应方法。

The following code is functionally correct, but I'm not comfortable with it. 以下代码在功能上是正确的,但我对它不满意。 Perhaps following this comfort path will lead to me being a purist. 也许遵循这条舒适的道路将导致我成为一个纯粹主义者。 Either way I would very much appreciate a nicer way to write this if such exists. 无论哪种方式,我都非常欣赏一种更好的方法来写这个如果存在的话。

public string GetColumnValue(string columnName)
        {
            object value = item[columnName];

            if (value == null)
                return string.Empty;

            if (value.GetType() == typeof(string))
            {
                return (string)value;
            }
            else if (value.GetType() == typeof(double))
            {
                return ((double)value).ToString();
            }
            ...
        }

If all you are doing is calling ToString , due to the polymorphic nature of C#, the ToString will call the correct implementation, even if all you have is a reference to Object. 如果您所做的只是调用ToString ,由于C#的多态性,ToString将调用正确的实现,即使您拥有的只是对Object的引用。

Eg: 例如:

var d=DateTime.Now;
object od=d;
Console.WriteLine(od.ToString());
Console.WriteLine(d.ToString());   //same as previous line

Depending on your list of acceptable types, you may want to consider using Convert.ToString and/or the IConvertable interface . 根据您的可接受类型列表,您可能需要考虑使用Convert.ToString和/或IConvertable接口

This will allow you to handle most of the primitive types in one shot. 这将允许您一次处理大多数基本类型。

You will still need to handle your null check, however. 但是,您仍然需要处理空检查。

edit 编辑

Test codes are here if anyone is interested: http://gist.github.com/raw/305787/dc5349d9f6fa37ee5d621b43ec92dade60fe1c8d/ToStringTests.cs 如果有人有兴趣,测试代码在这里: http//gist.github.com/raw/305787/dc5349d9f6fa37ee5d621b43ec92dade60fe1c8d/ToStringTests.cs

Below you will find my original answer. 您将在下面找到我的原始答案。 Someone pointed out that you might have a type which does not have a ToString() you like (because it uses Object or something higher up in the chain). 有人指出你可能有一个没有你喜欢的ToString()的类型(因为它使用了Object或链中更高的东西)。 The best way to handle this in 3.0+ is with a extension method like this: 在3.0+中处理此问题的最佳方法是使用这样的扩展方法:

    public static class ToStringExpander
    {
       public static string MyToString (this Object x)
       {
          return x.ToString();
       }

       public static string MyToString (this mytype x)
       {
          return "This is the to string of mytype!";
       }
    }

Now mytype will work with the GetColumnValue below if you change ToString() to MyToString() 现在,如果将ToString()更改为MyToString(),mytype将使用下面的GetColumnValue

original post 原帖

This will do what you want. 这将做你想要的。

   public string GetColumnValue(string columnName)
    {
        object value = item[columnName];

        if (value == null)
            return string.Empty;

        return object.ToString();
    }

or if you want to look old school: 或者如果你想看老派:

   public string GetColumnValue(string columnName)
    {
        return (item[columnName] == null ? string.Empty : item[columnName].ToString());
    }

of course true old school would be to make a #define macro... 当然,真正的老派将是制作#define宏...

Why can't you just use .ToString() on value since .ToString() is inherited from object? 为什么你不能在value上使用.ToString(),因为.ToString()是从对象继承的? The .ToString() for the appropriate type further up the inheritance chain will be called. 将调用继承链上的适当类型的.ToString()。

ToString() is a virtual method. ToString()是一个虚方法。 This means that any calls to that method will, at runtime, select the correct implementation (the "most derived type"). 这意味着对该方法的任何调用都将在运行时选择正确的实现(“最派生类型”)。 Since all the primative types override ToString() to do the correct thing, there is no reason for any casting to any type of variable. 由于所有主要类型都覆盖ToString()以执行正确的操作,因此没有理由将任何类型的变量转换为任何类型的变量。

For a virtual method, the type of the variable does not matter in selecting the correct implementation. 对于虚方法,变量的类型在选择正确的实现时无关紧要。 All that matters is runtime type of the object being referenced. 重要的是被引用对象的运行时类型。

int x = 10;
object o = x;
x.ToString();
o.ToString();

Both calls to ToString() will execute the same code (minus the unboxing that occurs in the object version, since int is a value type). ToString()两次调用都将执行相同的代码(减去object版本中发生的取消装箱,因为int是值类型)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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