Почему вам нужно указать универсальный тип для следующего кода - PullRequest
1 голос
/ 18 апреля 2011

У меня есть интерфейс

public interface ITcpSerializable<T>
{
    Byte[] Serialize();
    T Deserialize(Byte[] data);
}

В моем отдельном классе я хочу показать следующее свойство.

public List<ITcpSerializable> RegisteredTypes { get; set; }

Проблема в том, что я получаю следующую ошибку.

Использование универсального типа Для 'ITcpSerializable' требуется 1 тип аргументы

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

Есть ли способ обойти эту проблему? Надеюсь, то, что я пытаюсь сделать, ясно.

РЕДАКТИРОВАТЬ: ОК, я полностью набрал то, что я пытался объяснить. Просто нажал, что мое мышление было полностью искажено. Пожалуйста, посмотрите на этот вопрос для того, что я на самом деле спрашивал: Ограничить публичное свойство определенными типами в Списке

Ответы [ 4 ]

4 голосов
/ 18 апреля 2011

Вы должны сделать ITcpSerializable форму ITcpSerializable<T>.Затем унаследуйте это от вашей универсальной версии.

interface ITcpSerializable { }
interface ITcpSerializable<T> : ITcpSerializable { }
2 голосов
/ 18 апреля 2011

Вы можете создать неуниверсальный ITcpSerializable и наследовать ITcpSerializable<T> из нового неуниверсального интерфейса.

1 голос
/ 18 апреля 2011

Определение аргумента универсального типа в интерфейсе разработано так, чтобы при десериализации объекта данного типа требовались безопасные для типа результаты определенного типа.

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

Я понимаю, что вы хотите требовать наличия строго типизированного десериализатора, но имеет смысл использовать какой-то другой шаблон (например, Factory)

Кроме того, ваши входные данные являются байтами [] - если нет каких-либо других метаданных, у вас нет возможности узнать, какой из ITCPSerializable необходимо вызвать, чтобы получить правильный конкретный тип.

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

Метод сериализации имеет смысл - потому что разумно запрашивать объект для сериализованного экземпляра самого себя, но наоборот, обычно это делается другими способами.

Таким образом, решение вашей проблемы состояло бы в том, чтобы удалить определение универсального типа (которое вам не помогает) и метод Deserialize (который не имеет смысла в этом контексте), и просто оставить метод Serialize.

как в:

 public interface ITcpSerializable
{
    Byte[] Serialize();
}

И реализовать десериализацию с использованием фабрики.

0 голосов
/ 18 апреля 2011

Возможно, вы захотите сделать свой отдельный класс также общим, например:

public class MyClass<T> {
    public List<ITcpSerializable<T>> RegisteredTypes { get; set; }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...