如何检测当前类型是否有“ToString”覆盖方法?

时间:2012-11-26 08:16:48

标签: c# reflection

  

可能重复:
  How to determine if the MethodInfo is an override of the base method

通常,当我们执行任何复杂类型的“ToString”方法时,它将返回当前类型名称,如下面的字符串,除了有“ToString”覆盖方法。

  

System.Data.Entity.DynamicProxies.UserRole_D77A004638495805D68478322DF47F48540438D82DC9A5A0E1B0B2A181E4A100

我想要一些逻辑来检测关于此的当前类型,因为我尝试将数据导出为ex​​cel格式。但是模型的某些属性是复杂类型,没有定义“ToString”方法。对于普通用户,此属性的输出无用。

enter image description here

谢谢,

4 个答案:

答案 0 :(得分:4)

您可以检查methodInfo to string

上的DeclaringType
if (methodInfo.DeclaringType != typeof(YourObject)) {
    ...
}

system.reflection.methodinfo

答案 1 :(得分:4)

我认为这种检查特定类型是否覆盖ToString的方法有点脆弱。我们可以通过其他几种方式解决这个问题。

首先,如果字符串表示是必需,您可以使用一种方法添加额外的mixin接口,如IObjectDescriptor:string GetDescription。并且你可以要求来自每个类型的这个实现(如果类不是实现,它会抛出异常)。

第二种方法(如果我们不想改变现有的代码库)是使用单独的helper类,它将有一个方法:ConvertToString:

static class ToStringHelper
{
  // We can use Generic method to prevent boxing
  public string ConvertToString(object o)
  {
    var sb = new StringBuilder();
    // using reflection to access all public properties, for example

    return sb.ToString();
  }
}

在这两种情况下,您和您的客户之间的意图和“合同”将更加明确。在第一种情况下,如果type不是实现特定接口,你将抛出异常,使用第二种方法,你将获得至少一致的行为。

答案 2 :(得分:3)

你当然可以通过反思来做到这一点。另一种可能为您提供所需但不使用反射的方法是:

if (this.ToString() != this.GetType().ToString())
{
    // This Type or one of its base types has overridden object.ToString()
}

请注意,您可能想要检查当前类型或任何基类型(对象除外)是否已覆盖ToString()。作为一个人为的例子,从Exception派生的所有类型都会从ToString()返回一个合理的值(异常详细信息包括堆栈跟踪),但不是全部覆盖Exception.ToString()

答案 3 :(得分:1)

您可以使用IsSubclassOf对象和DeclaringType方法。

public class BaseClass
{
    public string Name;

    public virtual void Write(string val)
    {
    }
}

public class SubClass : BaseClass
{
    public string Address;

    public override void Write(string val)
    {
        base.Write(val);
    }
}

测试代码:

Type objType = obj.GetType();
MethodInfo info = objType.GetMethod("Write");
if (objType.IsSubclassOf(info.DeclaringType))
{

    Console.WriteLine("Not Override");
}
else
    Console.WriteLine("Override");