Универсальная оболочка и isAssignable от не работает - PullRequest
2 голосов
/ 07 декабря 2010

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

Обёртка выглядит так:

 class PropertyWrapper<T>
{
    private T _value;

    public PropertyWrapper(T value)
    {
        _value = value;
    }

    public PropertyWrapper()
    {
    }

    public static implicit operator T(PropertyWrapper<T> value)
    {
        return value._value;
    }

    public static implicit operator PropertyWrapper<T>(T value)
    {
        return new PropertyWrapper<T>(value);
    }

}

У него есть неявный оператор преобразователя, так что программист может работать с ним так же, как он работает с упакованным типом.

Теперь у меня есть следующий код:

        PropertyWrapper<Int32> wrapped = new PropertyWrapper<Int32>();
        Int32 unwrapped;

        unwrapped = 42;

        wrapped = unwrapped; //working

        wrapped = 21; //working

        unwrapped = wrapped; //working

        if (wrapped.GetType().IsAssignableFrom(unwrapped.GetType())) //will return false.
        {
            foo();
        }

Теперь я вижу, что функция IsAssignableFrom работает правильно, потому что она говорит только о том, можно ли назначить переменную напрямую без какого-либо преобразования типа. Есть ли способ изменить класс Wrapper, чтобы обойти это? Поскольку примитивные типы в CLR (или структура) не позволяют наследовать от них, я понятия не имею, как с этим справиться. Есть идеи на этот счет?

Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 07 декабря 2010

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

var wrappedUnderlyingType = wrapped.GetType().GetGenericArguments().Single();

if (wrappedUnderlyingType.IsAssignableFrom(unwrapped.GetType()))
{
   foo();
}

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

1 голос
/ 07 декабря 2010

Определяемые пользователем операторы приведения являются обычными статическими методами со специальными именами.
CLR, в отличие от компилятора C #, не придает им никакого значения.

Не думаю, что вы будетесмог сделать это.
Вы можете попробовать этот трюк , но я не уверен, сработает ли он.

...