Кастинг для менее универсальных типов


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

object validator;  // An object known to implement IValidation<T>
object toValidate; // The object which can be validated by using the validator.

// Assume validator is IValidation<string> and toValidate string.

IValidation<object> validation
    = Proxy.CreateGenericInterfaceWrapper<IValidation<object>>( validator );

validation.IsValid( toValidate ); // This works! No need to know about the type.

// Assuming the validator validates strings, this will throw an InvalidCastException.
//validation.IsValid( 10 );

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

В CreateGenericInterfaceWrapper метод использует RunSharp для передачи кода. Этот исходный код, и расширенное объяснение можно найти в моем блоге.

Моими главными задачами являются:

  • Кто-нибудь сталкивался с такой случай раньше, и нашел лучший способ решить это?
  • Я пишу то, что я мог бы просто нашли в существующую библиотеку?

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

object validator;  // An object known to implement IValidation<T>
object toValidate; // The object which can be validated by using the validator.

// 'validator' can be any type validator which can validate 'toValidate'.

if ( validator is IValidation<string> )
{
    IValidation<string> validation = (IValidation<string>)validator;
    validation.IsValid( (string)toValidate );
}
else if ( validator is IValidation<int> )
{
    IValidation<int> validation = (IValidation<int>)validator;
    validation.IsValid( (int)toValidate );
}
else if ... // and so on to support any possible type ...


8810
3
задан 2 июля 2011 в 12:07 Источник Поделиться
Комментарии
2 ответа


Кто-нибудь сталкивался с такой случай раньше, и нашел лучший способ решить это?

Есть интерфейс IEnumerable рисунка:

public interface IValidation
{
bool IsValid(object obj);
}

public interface IValidation<T> : IValidation
{
bool IsValid(T t);
}

public abstract class BaseValidation<T> : IValidation<T>
{
public bool IsValid(object obj)
{
return IsValid((T)obj);
}

public abstract bool IsValid(T t);
}

Будет ли это лучше или нет, вопрос спорный, но как минимум должны быть знакомы любому, кто должен поддерживать ваш код.

5
ответ дан 2 сентября 2011 в 07:09 Источник Поделиться

Я недавно столкнулся с похожей проблемой, но взял вместо утка-типирование подход, который работает, обеспечивая тип предположения держать. В вашем случае, это то, что я бы написал:

var validatorType = validator.GetType();
validatorType.GetMethod("IsValid").Invoke(validator, toValidate);

Если есть перегрузки метода IsValid, вам потребуется указать тот, что с право тип аргумента в вызове GetMethod, но вы можете обнаружить, что из toValidate.Метод gettype().

0
ответ дан 3 июля 2011 в 04:07 Источник Поделиться