C# 转换为对象实际类型的干净方法

C# 转换为对象实际类型的干净方法,c#,sharepoint,casting,C#,Sharepoint,Casting,我所做的是在哈希表中查找特定字段的值。对象可以是一些基本类型,它们的值注定要放在XML中,但它作为对象从哈希表中出来。因此,我有一个问题,需要确定类型是什么,将其强制转换,然后将该类型用于字符串。如果我不需要强制转换它就好了,但是它会在对象类型上调用ToString,而不是在实际类型上调用对应的方法 下面的代码在功能上是正确的,但我对它感到不舒服。也许遵循这条舒适的道路会让我成为一个纯粹主义者。无论哪种方式,如果存在这样的情况,我都会非常感激用一种更好的方式来写这篇文章 public strin

我所做的是在哈希表中查找特定字段的值。对象可以是一些基本类型,它们的值注定要放在XML中,但它作为对象从哈希表中出来。因此,我有一个问题,需要确定类型是什么,将其强制转换,然后将该类型用于字符串。如果我不需要强制转换它就好了,但是它会在对象类型上调用ToString,而不是在实际类型上调用对应的方法

下面的代码在功能上是正确的,但我对它感到不舒服。也许遵循这条舒适的道路会让我成为一个纯粹主义者。无论哪种方式,如果存在这样的情况,我都会非常感激用一种更好的方式来写这篇文章

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

如果您所做的只是调用ToString,那么由于C的多态性,ToString将调用正确的实现,即使您所拥有的只是对Object的引用

例如:


根据您可接受类型的列表,您可能需要考虑使用和/或

这将允许您一次性处理大多数基本类型


但是,您仍然需要处理空检查。

既然.ToString是从对象继承的,为什么不能在值上使用.ToString呢?将调用继承链更上层的适当类型的.ToString。

edit

如果有人感兴趣,可在此查看测试代码:

下面你会找到我最初的答案。有人指出,您可能有一个类型没有您喜欢的ToString,因为它使用Object或链中更高的某个对象。在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!";
       }
    }
现在,如果将ToString更改为MyToString,mytype将使用下面的GetColumnValue

原职

这会满足你的要求

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

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

        return object.ToString();
    }
或者,如果你想看起来老派一些:

   public string GetColumnValue(string columnName)
    {
        return (item[columnName] == null ? string.Empty : item[columnName].ToString());
    }
当然,真正的老派做法是定义宏…

字符串是一种虚拟方法。这意味着对该方法的任何调用都将在运行时选择最派生类型的正确实现。因为所有的primative类型都重写ToString来做正确的事情,所以没有理由对任何类型的变量进行任何转换

对于虚拟方法,变量的类型在选择正确的实现时并不重要。重要的是被引用对象的运行时类型

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

对ToString的两个调用将执行相同的代码减去对象版本中发生的取消装箱,因为int是一个值类型。

仍然需要null检查。这对基本类型有效,但对自定义类型可能不太有效-取决于项[columnName]…中可以返回的内容,你能举个例子吗?我真的认为这不管用。因此,为了参数起见,如何在特定类型的继承树上显式调用ToString实现?@Reed:显然,在3.5+中处理此问题的最佳方法是使用helper函数。为您想要处理的每个类型创建一个没有您喜欢的ToString的帮助器。@Hogan-除非Circle用new而不是override来装饰它的ToString方法,否则表达式类型对调用哪个方法没有任何影响。只有对象的运行时类型才重要。ShapeCircleVar.ToString与AcirCleaVar.ToString完全相同。方法名称解析规则要求选择对象的成员方法,而不是范围内的任何扩展方法。所以我很确定你在这里的建议不会起作用。是的,我刚刚测试了它,我读的那本书暗示它会像我描述的那样,我把答案改成了一个新的解决方案。
int x = 10;
object o = x;
x.ToString();
o.ToString();