Nano Hash - криптовалюты, майнинг, программирование

Сопоставление общих свойств с отражением/приведением свойства к универсальному типу

Я использую отражение для отображения (установки свойств) одного класса (xSearchObject) из DTO (xSearchQuery). Я попытался сократить код, чтобы было легче увидеть, чего я пытаюсь достичь. Я не могу изменить SearchField, но могу изменить DTOSearchField.

  • Исходный класс имеет n свойств типа DTOSearchField<T>.
  • Целевой класс имеет n свойств типа SearchField<T>.
  • Источник и место назначения имеют одинаковое количество свойств с одинаковыми именами.

Тип свойства исходного класса

public class DTOSearchField<T> : IDTOSearchField
{
  public T EqualTo;
}

Тип свойства целевого класса:

public class SearchField<T> : ISearchField
{
  public void WhereEquals(T value)
  {
    _clauses.Add(_name + " = " + Converter.ConvertValueToSql(value));
  }
    
  // etc
}

Сопоставление: (на основе облегченного объекта в Object Mapper) Я вполне могу сделать сопоставление, если вместо универсального DTOSearchField<T> у меня есть, например, классы StringDTOSearchField, IntDTOSearchField и т.д., и я приведу их к ним. Итак, для каждого исходного свойства:

if (sourceVal.GetType().IsAssignableFrom(typeof(StringDTOSearchField)))
{
  var destinationProperty = destinationPropertyAccessor.GetPropertyValue(destination, propertyMatch.DestinationProperty.Name) as SearchField<string>;

  var sourceStringField = sourceVal as StringSearchField;
  if (sourceStringField != null)
  {
    if (!string.IsNullOrEmpty(sourceStringField.EqualTo)) destinationProperty.WhereEquals(sourceStringField.EqualTo);
  }
}
else if (sourceVal.GetType().IsAssignableFrom(typeof(IntDTOSearchField)))
{
  // Etc
}

Или я мог бы оставить общий DTOSearchField<T> и выполнить загрузку If-Then-elses на основе:

Type t = sourceVal.GetType().GetGenericArguments()[0];

привести к соответствующему типу,

Но я чувствую, что должен быть в состоянии сделать что-то вроде:

Type t = sourceVal.GetType().GetGenericArguments()[0];
var destinationProperty = destinationPropertyAccessor.GetPropertyValue(destination, propertyMatch.DestinationProperty.Name) as SearchField<t>;
destinationProperty.WhereEquals(sourceVal.EqualTo.Value); 

Поскольку sourceVal — это DTOSearchField<T>, а destinationProperty — это SearchField<T>, и оба они имеют свойства типа T, кажется, что не должно иметь значения, если вы не знаете, что такое T, до времени выполнения.

Я понимаю, что актерский состав не будет работать, поскольку T неизвестен до времени выполнения. Есть ли способ добиться того, чего я хочу, кроме If-Then-Else для каждого возможного типа? Кажется, это лишает преимущества использования дженериков, если мне приходится это делать.

Спасибо,

02.10.2012

Ответы:


1

Вы можете просто вызвать метод WhereEquals через отражение, но я бы рекомендовал использовать дженерики в своих интересах следующим образом (поскольку у вас есть доступ для изменения DTOSearchField):

public interface IDTOSearchField
{
    void MapToSearchField(ISearchField searchField);
}

public class DTOSearchField<T> : IDTOSearchField
{
    public T EqualTo;

    public void MapToSearchField(ISearchField searchField)
    {
        if (!(searchField is SearchField<T>))
        {
            throw new ArgumentException("SearchField must be of type " + typeof(T).FullName + ".", "searchField");
        }

        ((SearchField<T>)searchField).WhereEquals(EqualTo);
    }
}

Затем вы можете использовать этот новый метод в интерфейсе для отображения следующим образом:

    public void MapField(IDTOSearchField source, ISearchField destination)
    {
        source.MapToSearchField(destination);
    }

Если вы не хотите, чтобы класс DTOSearchField знал о классе SearchField, есть способы обойти это, но это слишком много для этого ответа.

23.12.2012
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..