如何确定一个对象是否可以将 ToString 转换为值或类型名称?
How can I determine if an object can ToString into value or type name?
我正在编写 php 服务和我们的 crm 之间的互操作。我需要做的一件事是确保简单类型转换为 ToString() 以便稍后在 json 转换器中使用。
我什至不确定 'simple types' 的名称是什么,但可以这样定义... "an object that represents a low level variable type, containing a single value, not a class or anything with executable functions etc"
我发现 int、string、bool、double 和令人惊讶的枚举将 ToString() 与相当可预测的结果。
int x = 0;
bool y = true;
double z = 1.59 // money
CustomEnum theEnum = CustomEnum.somevalue;
x.ToString() 结果为“0”
y.ToString() 结果为 "true"
z.ToString() 结果为“1.59”
theEnum.ToString() 结果为 "somevalue"
但是如果我使用这个:
List<int> iList = new List<int>();
iList.Add(1);
MyClass theClass = new MyClass();
iList.ToString() 结果为 "System.Collections.Generic.List`1[System.Int32]"
theClass.ToString() 结果为 "STTI.NKI.Interop.MyClass"
我不限于列表。我可以有一个 ExpandoObject,或者 class 等等
我完全理解为什么会发生这种情况,我想知道是否有一种快速方法可以确定未知类型的对象是否将 ToString() 转换为预期值,而不是类型名称。我发现做类似
的事情是一种反模式
switch (theObject.GetType())
case typeof(int):
case typeof(bool):
case typeof(doulble):
etc
我不确定这些术语是什么,因此很难用谷歌搜索我的答案。
选项 1:确保每个对象都将覆盖 ToString()。
选项 2:使用反射获取所有对象属性并连接它们。
也许你可以做类似的事情:
bool ToStringIsTyped<T>(T myObj)
{
return myObj.ToString().Contains(typeof(T).FullName);
}
它可能并非在所有情况下都有效,但可能会得到扩展
所以您想检查一个类型是否有重写的 ToString
方法?为什么不检查 ToString
返回的值是否等于 ToString
的默认实现返回的值?
从here我们知道ToString
的默认实现是
return GetType().ToString();
因此,我们可以使用它来检查对象是否已覆盖 ToString
方法:
bool toStringOverridden = someObject.GetType().ToString() !=
someObject.ToString();
我认为这就是您要查找的内容,在 GetMethod 中,第二个参数是一个空数组,用于监视 .ToString(),只需将 i.GetType().GetMethod("ToString", new Type[] { }).DeclaringType == typeof(object)
转换为函数即可。
class Program
{
static void Main(string[] args)
{
int i = 55;
var s = "some string";
var x = new List<string>();
Console.WriteLine(i.ToString());
Console.WriteLine(i.GetType().GetMethod("ToString", new Type[] { }).DeclaringType == typeof(object));
Console.WriteLine(s.ToString());
Console.WriteLine(s.GetType().GetMethod("ToString",new Type[]{}).DeclaringType == typeof(object));
Console.WriteLine(x.ToString());
Console.WriteLine(x.GetType().GetMethod("ToString",new Type[]{}).DeclaringType == typeof(object));
}
}
ToString
方法是一个虚拟方法,默认实现在 Object
class 中定义,只是 return 对象类型的名称:
public virtual string ToString()
{
return this.GetType().ToString();
}
例如,int
将此方法重写为 return 有意义的表示。
你可以做的是使用反射来检测类型是否覆盖了 ToString
方法,如下所示:
public static bool OverridesToString(Type type)
{
return type.GetMethod("ToString", new Type[0]).DeclaringType != typeof(object);
}
如果是这样,ToString
方法很有可能会 return 一些有意义的东西。
...way to determine if an object of unknown type will ToString() into an expected value, and not the type name...
ToString()
在 object
上的默认实现,根据 documentation、returns "the fully qualified name of the object's type"。
因此我们可以提出这样的假设,即无论何时覆盖 ToString(),它的输出都将是您在问题中指定的意义上的 "useful"。
要检测调用的函数是否是覆盖,我们可以使用this answer,像这样:
if(typeof(ObjectX).GetMethod("ToString").DeclaringType == typeof(ObjectX))
{
/* ObjectX has overridden ToString() */
}
else
{
/* ObjectX has inherited ToString() from its base class(es) */
}
我正在编写 php 服务和我们的 crm 之间的互操作。我需要做的一件事是确保简单类型转换为 ToString() 以便稍后在 json 转换器中使用。
我什至不确定 'simple types' 的名称是什么,但可以这样定义... "an object that represents a low level variable type, containing a single value, not a class or anything with executable functions etc"
我发现 int、string、bool、double 和令人惊讶的枚举将 ToString() 与相当可预测的结果。
int x = 0;
bool y = true;
double z = 1.59 // money
CustomEnum theEnum = CustomEnum.somevalue;
x.ToString() 结果为“0”
y.ToString() 结果为 "true"
z.ToString() 结果为“1.59”
theEnum.ToString() 结果为 "somevalue"
但是如果我使用这个:
List<int> iList = new List<int>();
iList.Add(1);
MyClass theClass = new MyClass();
iList.ToString() 结果为 "System.Collections.Generic.List`1[System.Int32]" theClass.ToString() 结果为 "STTI.NKI.Interop.MyClass"
我不限于列表。我可以有一个 ExpandoObject,或者 class 等等
我完全理解为什么会发生这种情况,我想知道是否有一种快速方法可以确定未知类型的对象是否将 ToString() 转换为预期值,而不是类型名称。我发现做类似
的事情是一种反模式switch (theObject.GetType())
case typeof(int):
case typeof(bool):
case typeof(doulble):
etc
我不确定这些术语是什么,因此很难用谷歌搜索我的答案。
选项 1:确保每个对象都将覆盖 ToString()。 选项 2:使用反射获取所有对象属性并连接它们。
也许你可以做类似的事情:
bool ToStringIsTyped<T>(T myObj)
{
return myObj.ToString().Contains(typeof(T).FullName);
}
它可能并非在所有情况下都有效,但可能会得到扩展
所以您想检查一个类型是否有重写的 ToString
方法?为什么不检查 ToString
返回的值是否等于 ToString
的默认实现返回的值?
从here我们知道ToString
的默认实现是
return GetType().ToString();
因此,我们可以使用它来检查对象是否已覆盖 ToString
方法:
bool toStringOverridden = someObject.GetType().ToString() !=
someObject.ToString();
我认为这就是您要查找的内容,在 GetMethod 中,第二个参数是一个空数组,用于监视 .ToString(),只需将 i.GetType().GetMethod("ToString", new Type[] { }).DeclaringType == typeof(object)
转换为函数即可。
class Program
{
static void Main(string[] args)
{
int i = 55;
var s = "some string";
var x = new List<string>();
Console.WriteLine(i.ToString());
Console.WriteLine(i.GetType().GetMethod("ToString", new Type[] { }).DeclaringType == typeof(object));
Console.WriteLine(s.ToString());
Console.WriteLine(s.GetType().GetMethod("ToString",new Type[]{}).DeclaringType == typeof(object));
Console.WriteLine(x.ToString());
Console.WriteLine(x.GetType().GetMethod("ToString",new Type[]{}).DeclaringType == typeof(object));
}
}
ToString
方法是一个虚拟方法,默认实现在 Object
class 中定义,只是 return 对象类型的名称:
public virtual string ToString()
{
return this.GetType().ToString();
}
例如,int
将此方法重写为 return 有意义的表示。
你可以做的是使用反射来检测类型是否覆盖了 ToString
方法,如下所示:
public static bool OverridesToString(Type type)
{
return type.GetMethod("ToString", new Type[0]).DeclaringType != typeof(object);
}
如果是这样,ToString
方法很有可能会 return 一些有意义的东西。
...way to determine if an object of unknown type will ToString() into an expected value, and not the type name...
ToString()
在 object
上的默认实现,根据 documentation、returns "the fully qualified name of the object's type"。
因此我们可以提出这样的假设,即无论何时覆盖 ToString(),它的输出都将是您在问题中指定的意义上的 "useful"。
要检测调用的函数是否是覆盖,我们可以使用this answer,像这样:
if(typeof(ObjectX).GetMethod("ToString").DeclaringType == typeof(ObjectX))
{
/* ObjectX has overridden ToString() */
}
else
{
/* ObjectX has inherited ToString() from its base class(es) */
}