2016-09-16 2 views
4

Я пишу interop между php-сервисом и нашим crm. Одна из вещей, которую мне нужно сделать, - убедиться, что простые типы преобразуются в ToString() для использования позже в json-конверторе.Как определить, может ли объект ToString присвоить значение или имя типа?

Я не уверен, что это имя для «простых типов», но его можно определить следующим образом ... »объект, представляющий тип переменной низкого уровня, содержащий одно значение, а не класс или что-либо еще с исполняемые функции и т. д. »

Я обнаружил, что 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 приводит к "1,59"

theEnum() приводит к "истинной"

z.ToString() .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 или класс и т. Д.

Я понимаю ТОЧНО, почему это происходит, и я хочу знать, есть ли быстрый способ определить, будет ли объект неизвестного типа ToString() в ожидаемое значение, а не имя типа. Я считаю, что антипаттерны сделать что-то вроде

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

Я не уверен, что эти термины, так прибегая к помощи моему ответ оказывается трудным.

+0

Если список, используйте string.join («», MyList), чтобы получить строку CSV из все значения –

+0

Результат всегда является строкой, поэтому как вы можете получить значение? (за исключением 'string.ToString') – leppie

+3

well Если вы контролируете типы, которые будет отображаться вашим сервисом/интерфейсом, вы можете просто убедиться, что каждый экспонированный объект переопределяет ToString() таким образом, что он отображает читаемое представление содержимого. @leppie, если я правильно понял, OP хочет знать, можно ли проверять тип для того, будет ли его переопределение ToString() (или базовый класс по умолчанию) отображать сущность содержимого объекта или представление его типа/generic – dlatikay

ответ

2

Итак, вы хотите, чтобы проверить, есть ли тип в перекрытый ToString метод ? Почему бы просто не проверить, является ли значение, возвращаемое ToString, равным значению, возвращаемому реализацией по умолчанию ToString?

С here, мы знаем, реализация по умолчанию ToString является

return GetType().ToString(); 

Таким образом, мы можем использовать это, чтобы проверить, является ли объект переопределил ToString метод:

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

Это отличный трюк. Я могу использовать это, чтобы сделать мое сравнение. Я собираюсь либо вернуть myobject.ToString(), если ToString!= Введите имя или выведите ошибку, если они равны. Это также является технически правильным ответом, так как я попросил способ сделать это. Ваше истинное/ложное решение соответствует моему вопросу лучше всего, хотя здесь есть МНОГО хороших ответов и много полезной информации. – CarComp

0

Вариант 1: убедитесь, что каждый объект перезапишет ToString(). Вариант 2: используйте отражение, чтобы получить все свойства объекта и выполнить их.

0

Может быть, вы можете сделать что-то похожее на это:

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

Он не может работать во всех случаях, но, возможно, можно было бы расширить

0

Я думаю, что это что вы ищете, в 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)); 
     } 
    } 
2

ToString метод является виртуальным и реализация по умолчанию определяется в Object классе и просто возвращает имя типа объекта:

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

int, например, переопределяет этот метод для возвращения значимого представления.

Что вы можете сделать, это использовать отражение для определения переопределяет ли тип в ToString метод, как это:

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

Если это так, есть очень хороший шанс, что метод ToString будет возвращать что-то значимое.

+1

Не было бы более полезно сравнивать 'obj.ToString()' с 'obj.GetType(). ToString()'? Даже если объект переопределяет 'ToString', он все равно может вернуть имя типа. – Sweeper

+0

@Sweeper, Почему кто-то переопределяет 'ToString' только для того, чтобы вернуть имя типа? Эти подходы - все эвристики. Что делать, если кто-то возвращает случайную строку? Или не полное имя типа? –

0

... способ определить, является ли объект неизвестного типа будет ToString() в ожидаемое значение, а не имя типа ...

Реализация по умолчанию ToString() на object, согласно до documentation, возвращает «полное имя типа объекта».

Итак, мы можем придумать гипотезу, что всякий раз, когда ToString() переопределяется, ее вывод будет «полезен» в том смысле, который вы указали в вопросе.

Чтобы определить, является ли функция называется переопределяет, мы можем использовать в this answer, например, так:

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

Получение большого количества AmbiguousMatchExceptions с использованием этого кода. Я думаю, что для правильной работы новой части Type [0]. Также скобки не совсем правильные. – CarComp

Смежные вопросы