How can I determine if an object can ToString into value or type name?

…衆ロ難τιáo~ 提交于 2019-12-19 21:29:21

问题


I am writing an interop between a php service and our crm. One of the things I need to do is make sure that simple types get converted ToString() for use later in a json converter.

I am not sure even what the name is for 'simple types' but it can be defined like this... "an object that represents a low level variable type, containing a single value, not a class or anything with executable functions etc"

I've found that int, string, bool, double, and surprisingly enum will ToString() with pretty predictable results.

int x = 0;
bool y = true;
double z = 1.59 // money
CustomEnum theEnum = CustomEnum.somevalue;

x.ToString() results in "0"

y.ToString() results in "true"

z.ToString() results in "1.59"

theEnum.ToString() results in "somevalue"

But if I use this:

List<int> iList = new List<int>();
iList.Add(1);

MyClass theClass = new MyClass();

iList.ToString() results in "System.Collections.Generic.List`1[System.Int32]" theClass.ToString() results in "STTI.NKI.Interop.MyClass"

I'm not limited to lists. I could have an ExpandoObject, or a class etc.

I understand EXACTLY why this happens, and I want to know if there is a quick way to determine if an object of unknown type will ToString() into an expected value, and not the type name. I find it an antipattern to do something like

switch (theObject.GetType())
 case typeof(int):
 case typeof(bool):
 case typeof(doulble):
etc

I am not sure what the terms are, so googling my answer is proving difficult.


回答1:


So you want to check whether a type has a overridden ToString method? Why not just check whether the value returned by ToString is equal to the value returned by the default implementation of ToString?

From here, we know the default implementation of ToString is

return GetType().ToString();

So, we can use this to check whether an object has overridden the ToString method:

bool toStringOverridden = someObject.GetType().ToString() !=
    someObject.ToString();



回答2:


The ToString method is a virtual one and the default implementation is defined in the Object class and simply returns the name of the type of the object:

public virtual string ToString()
{
  return this.GetType().ToString();
}

int for example, overrides this method to return a meaningful representation.

What you can do is use reflection to detect whether a type overrides the ToString method like this:

public static bool OverridesToString(Type type)
{
    return type.GetMethod("ToString", new Type[0]).DeclaringType != typeof(object);
}

If it does, there is a very good chance that the ToString method would return something meaningful.




回答3:


Option 1: make sure that every Object will overwrite ToString(). Option 2: Use reflection to get all object properties and concat them.




回答4:


Maybe you can do something similar to this:

bool ToStringIsTyped<T>(T myObj)
{
    return myObj.ToString().Contains(typeof(T).FullName);
}

It may not work in all cases, but possibly could be expanded




回答5:


I Think this is what you are looking, in the GetMethod the second argument is an empty array to watch for the .ToString(), just convert the i.GetType().GetMethod("ToString", new Type[] { }).DeclaringType == typeof(object) to a function and there you go.

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



回答6:


...way to determine if an object of unknown type will ToString() into an expected value, and not the type name...

The default implementation of ToString() on object, according to documentation, returns "the fully qualified name of the object's type".

So we could come up with the hypothesis that whenever ToString() is overridden, its output will be "useful" in the sense you specified in the question.

To detect whether a function called is an override, we can make use of this answer, like so:

if(typeof(ObjectX).GetMethod("ToString").DeclaringType == typeof(ObjectX))
{
    /* ObjectX has overridden ToString() */
}
else
{
    /* ObjectX has inherited ToString() from its base class(es) */
}


来源:https://stackoverflow.com/questions/39537162/how-can-i-determine-if-an-object-can-tostring-into-value-or-type-name

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!