2015-11-11 9 views
0

Возможно ли, чтобы на C# было что-то, что я мог бы назвать зеркальным отображением динамического типа, из-за отсутствия лучшего термина?C# Тип Зеркальное отображение

скажем, переговоры приложения к базе данных, которая имеет несколько таблиц, каждая из которых имеет объект в коде обычного вида:

public class SomeEntity 
{ 
    int ID { get; set; } 
    string Name { get; set; } 
}; 

и т.д.

Теперь это возможно есть класс, который динамически отражает типы этих образований:

public class FilterType<T, U> 
{ 
    T Field1; 
    bool Apply<T>(T operand, T comparand); 
}; 

таким образом, что T динамически int, например?

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

Мне нужно это, чтобы иметь возможность фильтровать поля в таблице, и в идеале я хочу, чтобы это было как можно более общим с минимальной связью. Для того, чтобы добавить больше вещества, вот некоторый код из моих типов фильтров:

public interface IFilter 
{ 
    string Representation { get; } 
} 

public interface IFilterBinary : IFilter 
{ 
    bool Apply<T>(T source, T operand1, T operand2) where T : IComparable; 
} 

public interface IFilterUnary : IFilter 
{ 
    bool Apply<T>(T source, T operand) where T : IComparable; 
} 

public class IsGreaterOrEqual : IFilterUnary 
{ 
    public string Representation { get; } = ">="; 

    public bool Apply<T>(T source, T operand) where T : IComparable 
    { 
     return source.CompareTo(operand) >= 0; 
    } 
} 

Проблема в том, что, когда я пытаюсь использовать фильтры, я ударил загвоздка:

var property = typeof (User).GetProperties().Single(x => x.Name == rule.FieldName); 
var fieldValue = property.GetValue(user); 
var fieldType = property.PropertyType; 
var value = Convert.ChangeType(fieldValue, fieldType); // Here the return type is `object`, so this line is useless. 

Применение фильтра filter.Apply(value, operand) не работает, потому что value является object.

Спасибо.

+0

Ищете «var»? –

+1

Зачем вам это нужно? Как вы собираетесь работать с объектом, который обладает свойствами типов, которые вы не знаете во время разработки? –

+0

Мне понадобится это в более сложных случаях, когда зеркало не так просто, скажем, если я хочу выполнить некоторые операции над первым полем таблицы, не зная его типа заранее. –

ответ

1

Я думаю, что лучше для вас, используя DynamicLinq lib.

Что касается текущего подхода, если использовать отражение для получения значения, просто использовать его для вызова функции, например:

var property = typeof (User).GetProperty(rule.FieldName); 
var fieldValue = property.GetValue(user); 
var fieldType = property.PropertyType; 
var result = filter.GetType().GetMethod("Apply").MakeGenericMethod(fieldType).Invoke(filter, fieldValue, operand); 

, но в любом случае в этом случае результата был коробочным к объекту.

+0

Я изменил код, как вы предлагали, с некоторыми изменениями, чтобы заставить его работать (например, передать массив 'object', а не объект), и он действительно работает. Сказав это, я должен признать, что это уродливо. Так что, возможно, путь DynamicLinq может быть лучше. Я буду принимать это как правильный ответ через некоторое время - позвольте мне дать время, чтобы другие тоже ответили. –

+0

@ KristianD'Amato, конечно, вот почему в первой строке я говорю о DynamicLInq :-) – Grundy

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