У меня есть эта настройка в моем коде:
public abstract class ModelBase{}
public interface IModelbase<T>{}
public abstract class ModelBase<T> : ModelBase, IModelBase<T> {}
public class MyClass : ModelBase<int> {}
А потом мне дают объект FutureValue<MyClass>
от NHibernate, и я пытаюсь:
if (obj is IFutureValue<ModelBase>) // => false?
// or
if (obj is FutureValue<ModelBase>) // => false?
// (I changed NHibernate's source to make FutureValue public, for other uses)
Между тем, если я приведу его к типу напрямую:
if (((IFutureValue<MyClass>)obj).Value is ModelBase) // => true!
// or
if (((FutureValue<MyClass>)obj).Value is ModelBase) // => true!
... серьезно?Это в цепочке наследования, есть ли какая-то причина, по которой он не просматривается?Проверка объекта в отладчике показывает, что это на самом деле MyClass, и на нем есть методы и свойства ModelBase, поэтому я сомневаюсь, что это как-то связано с прокси-сервером NHibernate.
Почему бы .NET не искать наследованиецепи в такой ситуации?Есть ли какой-нибудь трюк с ключевыми словами / кастингом, который я могу выполнить, чтобы заставить его это сделать?Или я должен прибегнуть к большой неуклюжей установке, подобной:
if (obj is IFutureValue<MyClass>) return ((IFutureValue<MyClass>)obj).Value;
if (obj is IFutureValue<MyOtherClass>) return ((IFutureValue<MyOtherClass>)obj).Value;
// etc etc ad infinitum
edit: это в .NET 2.0
edit2: точный код (I)FutureValue:
public interface IFutureValue<T>
{
T Value { get; }
}
public class FutureValue<T> : IFutureValue<T>
{
public delegate IList<T> GetResult();
private readonly GetResult getResult;
public FutureValue(GetResult result)
{
getResult = result;
}
public T Value
{
get
{
var result = getResult();
if (result.Count == 0)
{
return default(T);
}
return result[0];
}
}
}
Я просто очень неправильно понимаю проблему ковариации / контравариантности (в этом случае, почему Func<Type2, Type2> f1 = MyMethod;
может быть приведено к Func<Type3, Type1> f2 = f1;
(где первый тип - тип возвращаемого значения), но вышекод не может сделать то же самое? Если только .NET 2.0 не работает с полиморфизмом?
edit3: мышление при наборе текста. Это потому, что IList<T>
определяет делегатов, которые принимают, скажем, производный тип, поэтомунужен Derived или DoublyDerived T, но тип возвращаемого значения может быть только T или Base? Поэтому я не могу разыграть ни одно из направлений ... Интересно, смогу ли я убедить NHibernate переключиться на IEnumerable<T>
в их Futures ... это решитэто?