Приведение одного общего к другому без ограничений класса - PullRequest
4 голосов
/ 13 июня 2011

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

public interface IDrilldown
{
   void AddCriteria<T>(T Criterion);
}

public class MyClass<W> : IDrilldown // where W : class
{
    void IDrilldown.AddCriteria<T>(T Criterion)
    {
       W value = Criterion as W;
       ...
    }
}

К сожалению, приведенное выше приведение не будет работать, если W не содержит консистент в коде.Я хотел бы иметь это с использованием типов значений.Это вообще возможно?

Я не могу сделать W и T одного типа.Мой интерфейс не имеет типа, связанного с ним глобально, только внутренние типы данных.

Это сделано для того, чтобы все списки могли иметь разные T

Ответы [ 2 ]

2 голосов
/ 13 июня 2011

Поможет ли вам динамическое ключевое слово?

Примерно так:

public interface IDrilldown
{
   void AddCriteria<T>(T Criterion);
}

public class MyClass : IDrilldown
{
    void IDrilldown.AddCriteria<T>(T criterion)
    {
       dynamic value = criterion;
       // can use typeof() to figure out type if needed...
       ...
    }
}
2 голосов
/ 13 июня 2011

Мне удалось найти способ сделать это, он немного хакерский, но позволяет работать:

class MyClass<W> : IDrilldown {
    void IDrilldown.AddCriteria<T>(T Criterion) {
        if (Criterion is W) {
            W value = (W)Convert.ChangeType(Criterion, typeof(W));
            // value is W, have fun
            // or - as Snowbear pointed out in the comments
            W value = (W)(object)Criterion;
            // works just as well....
        } else {
            // value is NOT W and could not be converted.
        }
    }
}

Единственный недостаток - Convert.ChangeType будет использовать преобразователи для переключения между внутреннимиобъекты, поэтому string value = (string)Convert.ChangeType(1, typeof(string)) будет работать и возвращать "1" вместо выдачи исключения.

Чтобы прояснить, как это работает, в документации указано:

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

, поэтому для работы этого метода с пользовательскими типами вам потребуется реализовать интерфейс IConvertible для преобразования одного пользовательского типа в любой другой тип.,В приведенном выше примере кода, если и T и W имеют одинаковый тип, Convert.ChangeType будет успешным, даже если пользовательский объект не реализует IConvertiable.

...