Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何检测当前类型的“已”;ToString";是否重写了方法?_C#_Reflection - Fatal编程技术网

C# 如何检测当前类型的“已”;ToString";是否重写了方法?

C# 如何检测当前类型的“已”;ToString";是否重写了方法?,c#,reflection,C#,Reflection,可能重复: 通常,当我们执行任何复杂类型的“ToString”方法时,它将返回当前类型名称,就像下面的字符串一样,除非有“ToString”重写方法 System.Data.Entity.DynamicProxies.UserRole\u D77A004638495805D6847322DF47F4854038D82DC9A5A0E1B0B2A181E4A100 我需要一些逻辑来检测当前类型,因为我试图将数据导出为excel格式。但该模型的某些属性是复杂类型,它并没有定义“ToString”方

可能重复:

通常,当我们执行任何复杂类型的“ToString”方法时,它将返回当前类型名称,就像下面的字符串一样,除非有“ToString”重写方法

System.Data.Entity.DynamicProxies.UserRole\u D77A004638495805D6847322DF47F4854038D82DC9A5A0E1B0B2A181E4A100

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


谢谢,

您可以在to字符串的methodInfo上检查DeclaringType

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

我认为这种检查特定类型是否重写ToString的方法有点脆弱。我们可以用其他几种方法来解决这个问题

首先,如果字符串表示是必需的,您可以使用一个方法添加额外的mixin接口,如IObjectDescriptor:string GetDescription。您可以从每种类型中要求此实现(如果类未实现,则抛出异常)

第二种方法(如果我们不想更改现有的代码库)是使用单独的助手类,该类将有一个方法: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();
  }
}

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

当然,您可以通过反射来实现这一点。另一种可能为您提供所需且不使用反射的方法是:

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

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

,您可以使用
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");

!=typeof(object)
如果中间类定义了覆盖是可以接受的。普通类如int、double、Guid、string是什么?它们仍然有效吗?您没有对ToString()方法的行为进行任何更改,只检查了它的一些属性。您可以检查是否正在检查值类型,如果是,则不必检查ToString()的重写。此解决方案仅检查派生的实例。但这不是这个问题的答案。你不能使用这个.ToString(),因为有时没有数据可供测试。@Soul\u Master,“没有数据可供测试”是什么意思。如果您的意思是没有该类型的实例,为什么要关心它的ToString()方法返回什么?有时,我得到了某个类的空列表,这意味着您无法使用this.ToString方法与其类型名进行比较。它几乎是一样的。但我很难找到老问题。我同意,这是一个更好的方法。它还允许您更轻松地国际化您的计划。我通常将ToString()视为仅用于调试目的,因为我们所有的程序都必须国际化和本地化,而ToString()是本地化内容的错误地方!(我不是说将ToString()与DateTime.ToString(字符串格式)等格式规范一起使用-显然,这是本地化字符串的正确方法。)我知道。我们可以创建一些逻辑来处理复杂的数据类型,或者创建一些类型(如DateTime)来生成首选格式。然而,对于任何网格控件中的导出按钮之类的一般建议功能,我们并不关心将对象序列化为字符串所使用的格式。