Можно ли псевдоним типа массива в C #? - PullRequest
6 голосов
/ 14 апреля 2011

Я пытаюсь сделать некоторые вещи сериализации / десериализации с пользовательским типом исключения. Этот тип имеет поле, определенное как:

private object[] resourceMessageParams;

У меня есть весь хороший и строго типизированный код с некоторой магией выражений Linq, но я хочу пойти еще дальше и сделать что-то вроде этого:

using ResourceMessageParamsType = object[];//<-- "Identifier expected" error here
/*...*/
private ResourceMessageParamsType resourceMessageParams;
/*...*/
this.resourceMessageParams = 
    (ResourceMessageParamsType)serializationInfo.GetValue(
        ReflectionHelper.GetPropertyNameFromExpression(() => 
            resourceMessageParams), typeof(ResourceMessageParamsType));

Вместо этого:

(object[])serializationInfo.GetValue(
    ReflectionHelper.GetPropertyNameFromExpression(() => 
        resourceMessageParams), typeof(object[]));

Чтобы учесть возможное изменение типа этого поля в будущем, поэтому в определении псевдонима придется изменить тип только один раз. Однако компилятор останавливается на object в using ResourceMessageType = object[];, жалуясь на то, что ожидается идентификатор. Изменение на Object[] несколько помогает, но на этот раз скобка подсвечивается тем же сообщением об ошибке.

Есть ли способ определить псевдоним для типа массива в c #?

Ответы [ 4 ]

8 голосов
/ 14 апреля 2011

Вы можете определить класс (или структуру) с именем ResourceMessageParamsType и определить неявные операторы для приведения к и от объекта [].

struct ResourceMessageParamsType
{
    private object[] value;

    private ResourceMessageParamsType(object[] value)
    {
        this.value = value;
    }

    public static implicit operator object[](ResourceMessageParamsType t)
    {
        return t.value;
    }

    public static implicit operator ResourceMessageParamsType(object[] value)
    {
        return new ResourceMessageParamsType(value);
    }
}
3 голосов
/ 14 апреля 2011

Проще говоря, вы не можете "псевдоним" типов массивов.

Вы можете обойти это, заключив вещи в struct, но это не отвечает на ваш вопрос.


Обновление:

Из стандарта ECMA,

используя псевдоним директивы:

using идентификатор = namespace-or-type-name ;

, который явно ничего не говорит о допустимости массивов.

(см. Стр. 100 для определения namespace-or-type-name .)

0 голосов
/ 14 апреля 2011
using ResourceMessageParamsType = System.Array;

Не то чтобы я делал вид, что понимаю, как этот "код сериализации защищает вас от возможных изменений в определении класса".

Интерфейсы были бы более чистым подходом, а вы рассматривали дженерики?

Комплексные модульные тесты IMO гарантируют, что, если кто-то изменит псевдоним, все коды десериализации будут работать.

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

Я бы просто получил свой тип из System.Array. Если я правильно истолковываю это, то, что вы описываете, это не ОО-подход, который вы использовали бы в простом C.

Обновление - я думаю, вы не можете создать подкласс System.Array. Может быть, есть способ обойти это.

...