1 2
Re[8]: Не работает своё преобразование типов в избранное  новое горячее всё    подписка   модер. 
От: dims12http://www.relativity.ru
Дата: 16.03.10 17:44
Оценка: :)
Здравствуйте, _FRED_, Вы писали:

_FR>Да какая разница как оно выглядит с наружи?


Так это ж "договор". Если я передаю туда какой-то параметр, то, значит, могу влиять на работу метода. А если параметр игнорируется, то, значит, в договоре одно, а на деле -- другое.

_FR>Я тебе суть показывал, что бы было максимально похоже на твой пример с Number из Явы.


Я понял. Но по логике, ведь, не похоже. IConvetible -- это станция пересадок между множеством типов, а Number -- это абстракция числа, являющаяся предком всех числовых типов.

_FR>Но не в том, о чём говоришь ты. Пока что ты лишь расписываешься в отсутствии знаний.


Всё правильно: у меня пока что не было знаний об этих дырках

Ну ладно, ладно: о фичах
Re[4]: Не работает своё преобразование типов в избранное  новое    модер. 
От: _FRED_ экспертProfile on Google
Дата: 17.03.10 06:58
Здравствуйте, _FRED_, Вы писали:

_FR>Разбоксить некоторое значение из object в неизвестно во что возможно, пожалуй, лишь с помощью "хаков" и дополнительных приседаний. Но после этого выбрать ещё и требуемый оператор преобразования во что-то другое… Тоже придётся много приседать. А оно нужно?


Во, кстати, пример приседаний:

using System;
using System.Linq.Expressions;

class Y { }

struct X
{
  public int Value { get; set; }

  public static explicit operator int(X value) {
    return value.Value;
  }

  public static implicit operator string(X value) {
    return value.Value.ToString();
  }

  public static implicit operator X(Y value) {
    return new X { Value = 4, };
  }
}

static class Program
{
  static void Main() {
    var i = CustomConvert<int>(new X { Value = 7, });
    var s = CustomConvert<string>(new X { Value = 8, });
    var x = CustomConvert<X>(new Y());
  }

  static T CustomConvert<T>(object value) {
    if(value == null) {
      throw new ArgumentNullException("value");
    }//if

    var param = Expression.Parameter(typeof(object));
    var unbox = Expression.Convert(param, value.GetType());
    var convert = Expression.Convert(unbox, typeof(T));
    var lambda = Expression.Lambda<Func<object, T>>(convert, param);
    var func = lambda.Compile();
    return func(value);
  }
}


Скомпилированный expression для продуктивной работы нужно кешировать, например так:
using System;
using System.Linq.Expressions;
using System.Collections.Generic;

// class Y { } … без изменений
// struct X … без изменений

static class Program
{
  // static void Main() … без изменений

  static T CustomConvert<T>(object value) {
    return CustomConverter<T>.Convert(value);
  }

  public class CustomConverter<T>
  {
    private static readonly Func<Type, Func<object, T>> Method = Memoize<Type, Func<object, T>>(Convert);

    public static T Convert(object value) {
      if(value == null) {
        throw new ArgumentNullException("value");
      }

      var convert = Method(value.GetType());
      return convert(value);
    }

    private static Func<object, T> Convert(Type type) {
      if(type == null) {
        throw new ArgumentNullException("type");
      }//if

      var param = Expression.Parameter(typeof(object));
      var unbox = Expression.Convert(param, type);
      var convert = Expression.Convert(unbox, typeof(T));
      var lambda = Expression.Lambda<Func<object, T>>(convert, param);
      return lambda.Compile();
    }
  }

  private static Func<T, TResult> Memoize<T, TResult>(this Func<T, TResult> function) {
    if(function == null) {
      throw new ArgumentNullException("function");
    }//if

    var map = new Dictionary<T, TResult>();
    return arg => {
      TResult value;
      if(!map.TryGetValue(arg, out value)) {
        value = function(arg);
        map.Add(arg, value);
      }//if
      return value;
    };
  }
}


Memoize же должен быть потокобезопасным, но этот вопрос я оставляю за рамками данного сообщения, ограничусь лишь ссылкой сюда.
What I've learned about software engineering: 1) Listen to smart people 2) Prefer simple to clever 3) Have no ego 4) Shut the fuck up.
Не бойтесь делиться своими методами работы. Большинству людей будет тупо лень их использовать.
Re: Не работает своё преобразование типов в избранное  новое    модер. 
От: nikov экспертMy buzz
Дата: 18.03.10 08:13
Оценка: +1
Здравствуйте, dims12, Вы писали:

D>Внутри object a лежит объект class A, у которого есть explicit преобразование к int.


D>Выражение int b= (int)a вызывает экспешн InvalidCastException, внутри которого ПО РУССКИ написано, что преобразование недопустимо.


Если используешь C# 4.0, то можно попробовать

int b = (int)(dynamic)a;
Re[2]: Не работает своё преобразование типов в избранное  новое    модер. 
От: ARMSoft 
Дата: 18.03.10 12:55
юзай:
public static int ToInt32(this object obj)
{
  IConvertible converter = obj as IConvertible;
  if(converter != null)
  {
    return converter.ToInt32(null);
  }
  
  return default(int);
}

void Foo(object o)
{
  int a = o.ToInt32();
}


и будет все выглядеть "красиво". Сравнивать Шарп с Явой/Питоном/etc. не никакого смысла, у каждого языка свои правила игры. И то, что валит ошибку в твоем коде — идеологически имхо верно (используя strong casting будь уверен, что там лежит именно твой тип данных), т.к. кастинг не полиморфный как в Яве (как я понял), иначе будет все безбожно тупить.
-------------------------
My professional profile
1 2