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)来生成首选格式。然而,对于任何网格控件中的导出按钮之类的一般建议功能,我们并不关心将对象序列化为字符串所使用的格式。