Мне нужно пройти через все свойства, реализующие интерфейс, и у меня есть свойство IntPtr, которое передает контенту IsAssignableFrom.
Есть ли другой способ проверить, реализует ли свойство интерфейс?
Это метод, который проходит через свойства:
protected void SetOwner()
{
IEnumerable<PropertyInfo> sourceProperties = this.GetType().GetProperties();
foreach (PropertyInfo pi in sourceProperties)
{
if (pi.Name != "Owner" && pi.DeclaringType.GetInterface("IOwnerSystem") != null)
//i tried this too: typeof(IOwnerSystem).IsAssignableFrom(pi.DeclaringType))
{
IOwnerSystem systm = (IOwnerSystem)pi.GetValue(this, null);
if (systm != null)
{
systm.Owner = this;
}
}
}
}
и это класс:
public abstract class Aircraft : OwnerSystem
{
//a bunch of properties...
public abstract IntPtr VideoWindow { get; }
}
pi.DeclaringType
- это тип, объявляющий свойство, а не тип свойства. В вашем случае DeclaringType
- это Aircraft
или один из его базовых классов. pi.PropertyType
этого вы должны использовать pi.PropertyType
.
typeof(interface).IsAssignableFrom(intptr)
возвращает true
Я не могу подтвердить ваше предположение, что любой интерфейс IsAssignableFrom(typeof(IntPtr))
:
interface I { }
…
Debug.Assert(!typeof(I).IsAssignableFrom(typeof(IntPtr)));
Это утверждение проходит, поэтому проблема должна лежать в другом месте; см. ответ Томаса Левеска.
При этом, на мой взгляд, использование IsAssignableFrom
лучше, чем выполнение теста с GetInterface
: я не проверял это, но я подозреваю, что он имеет лучшую производительность, не в последнюю очередь потому, что GetInterface
должен привязать имя типа к некоторому типу. typeof(IntPtr)
, с другой стороны, непосредственно преобразуется в токен метаданных компилятором; во время выполнения не требуется привязка.