Как объявить пользовательский псевдоним для System.Int32 [] в c # [duplicate]

Вот немного измененная версия элегантной реализации из книги «JavaScript: Хорошие детали».

ПРИМЕЧАНИЕ. Эта версия by является стабильной. Он сохраняет порядок первого сорта, выполняя следующий цепной сортировку.

Я добавил к нему параметр isAscending. Кроме того, он был преобразован в ES6 стандарты и «новые» хорошие части, как рекомендовано автором.

Вы можете сортировать как по возрастанию, так и по убыванию и сортировать по нескольким свойствам.

const by = function (name, minor, isAscending=true) {
    const reverseMutliplier = isAscending ? 1 : -1;
    return function (o, p) {
        let a, b;
        let result;
        if (o && p && typeof o === "object" && typeof p === "object") {
            a = o[name];
            b = p[name];
            if (a === b) {
                return typeof minor === 'function' ? minor(o, p) : 0;
            }
            if (typeof a === typeof b) {
                result = a < b ? -1 : 1;
            } else {
                result = typeof a < typeof b ? -1 : 1;
            }
            return result * reverseMutliplier;
        } else {
            throw {
                name: "Error",
                message: "Expected an object when sorting by " + name
            };
        }
    };
};

let s = [
    {first: 'Joe',   last: 'Besser'},
    {first: 'Moe',   last: 'Howard'},
    {first: 'Joe',   last: 'DeRita'},
    {first: 'Shemp', last: 'Howard'},
    {first: 'Larry', last: 'Fine'},
    {first: 'Curly', last: 'Howard'}
];

// Sort by: first ascending, last ascending
s.sort(by("first", by("last")));    
console.log("Sort by: first ascending, last ascending: ", s);     // "[
//     {"first":"Curly","last":"Howard"},
//     {"first":"Joe","last":"Besser"},     <======
//     {"first":"Joe","last":"DeRita"},     <======
//     {"first":"Larry","last":"Fine"},
//     {"first":"Moe","last":"Howard"},
//     {"first":"Shemp","last":"Howard"}
// ]

// Sort by: first ascending, last descending
s.sort(by("first", by("last", 0, false)));  
console.log("sort by: first ascending, last descending: ", s);    // "[
//     {"first":"Curly","last":"Howard"},
//     {"first":"Joe","last":"DeRita"},     <========
//     {"first":"Joe","last":"Besser"},     <========
//     {"first":"Larry","last":"Fine"},
//     {"first":"Moe","last":"Howard"},
//     {"first":"Shemp","last":"Howard"}
// ]

6
задан Stanislav Kniazev 13 April 2011 в 23:21
поделиться

4 ответа

Проще говоря, вы не можете использовать типы массивов «alias».

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


Обновление:

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

using-alias-директива:

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

, который явно ничего не говорит о разрешенных массивах.

(см. стр. 100 о том, как определено имя имя пространства имен или имя .)

3
ответ дан Mehrdad 21 August 2018 в 09:32
поделиться
  • 1
    Спасибо, что ответили на заданный вопрос. У вас есть доказательная ссылка? – Stanislav Kniazev 13 April 2011 в 22:52
  • 2
    @Stanislav: Вы действительно не можете «доказать». что-то не существует, если вы не смотрите на все возможности и не управляете ими. Если вы хотите строгое доказательство, тогда вам нужно будет прочитать стандарт ECMA и увидеть, что нет никакого способа сделать это, и, следовательно, это невозможно ... в противном случае, однако, вы мне придется «поверить мне на слово». :) – Mehrdad 13 April 2011 в 22:54
  • 3
    Да, я думал, что у вас может быть определенный абзац из стандартного понятия, запрещающего типы массивов псевдонимов. Подождем ответа Джона Скита, он знает стандарт наизусть. – Stanislav Kniazev 13 April 2011 в 22:58
  • 4
    @Stanislav: Хорошо, вот что-то из стандарта; см. мой обновленный ответ. – Mehrdad 13 April 2011 в 23:10

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

Update. Думаю, вы не можете подклассы System.Array. Возможно, вокруг есть способ.

0
ответ дан dnewcome 21 August 2018 в 09:32
поделиться
  • 1
    Ну, это может быть не классический подход OO, но есть языковая особенность сглаживания типа, «используя MyType = SomeLongNameSpace.SomeType; & quot; будет работать нормально, но не для массивов. Я пытаюсь защитить код сериализации от возможных изменений в определении класса. – Stanislav Kniazev 13 April 2011 в 22:35
using ResourceMessageParamsType = System.Array;

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

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

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

0
ответ дан Robert Paulson 21 August 2018 в 09:32
поделиться

Вы можете определить класс (или структуру), называемый 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);
    }
}
7
ответ дан tuxedo25 21 August 2018 в 09:32
поделиться