Сравнение C# и PascalABC.NET

Здесь будут выкладываться сравнения языков C# и PascalABC.NET с различных точек зрения.

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

Auto implemented properties - Автоматически реализуемые свойства

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

Объявление на C#:

public T Name { get; set; }

Объявление на PascalABC.NET:

public auto property Name: T;

Возможности, предлагаемые C#:

  • модификаторы доступа для get/set специальных методов
  • возможность инициализации автосвойств, подобно полям
  • возможность применять атрибуты к свойствам и их полям

Возможности, предлагаемые PascalABC.NET:

  • возможность инициализации автосвойств, подобно полям
  • возможность применять атрибуты к свойствам

Рассмотрим предлагаемый функционал подробнее.

Модификаторы доступа для get/set специальных методов

C#:
namespace CSharpApplicationTest
{
    internal class Program<T>
    {
        public T Name { get; private set; }

        private static void Main(string[] args)
        {
        }
    }
}

PascalABC.NET: данной возможности нет, но решить данную проблему можно введением поля с необходимым уровнем доступа.

Пример применения: свойство коллекции Count (например, в List<T>), которое возможно читать из вне класса коллекции и менять внутри него.

Возможность инициализации автосвойств, подобно полям

C#:
namespace CSharpApplicationTest
{
    internal class Program<T>
    {
        public T Name { get; set; } = default;

        private static void Main(string[] args)
        {
        }
    }
}

PascalABC.NET:

type
  ClassT<T> = class
    public auto property Name: T := default(T);
  end;

begin
end.

Пример применения: установка значений свойств по умолчанию и разгрузка кода конструктора как побочный эффект.

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

C#:
using System;

namespace CSharpApplicationTest
{
    internal class Program<T>
    {
        [field: NonSerialized]
        public T Name { get; set; }

        private static void Main(string[] args)
        {
        }
    }
}

PascalABC.NET: данной возможности нет, но решить данную проблему можно введением поля с необходимым атрибутом.

Пример применения: отмена сериализации специального свойства, такого, например, как SyncRoot.

1 лайк

Extensions - Методы и операторы расширения

Будем рассматривать сравнение на примере самописного типа Point. Обращаю внимание, что каждому операторы следует ставить в соответствие определённый метод, поскольку не каждый .NET язык поддерживает операторы расширения.

Объявление на C#

using System;

namespace CSharpApplicationTest
{
    public struct Point
    {
        public int X { get; set; }

        public int Y { get; set; }

        public Point(int x, int y)
        {
            X = x;
            Y = y;
        }

        public override string ToString()
        {
            return $"{X}, {Y}";
        }
    }

    internal static class Program
    {
        private static void Main(string[] args)
        {
        }
    }
}

Объявление на PascalABC.NET:

uses System;

type
  PointT = record
    public auto property X: integer;
    public auto property Y: integer;
    
    constructor(x, y: integer);
    begin
      self.X := x;
      self.Y := y;
    end;
    
    function ToString(): string; override := $'{X}, {Y}';
  end;

begin
end.

Возможности, предлагаемые C#:

  • Методы расширения

Возможности, предлагаемые PascalABC.NET:

  • Методы расширения
  • Операторы расширения

Рассмотрим предлагаемый функционал подробнее.

Методы расширения

C#:

using System;

namespace CSharpApplicationTest
{
    public struct Point
    {
        public int X { get; set; }

        public int Y { get; set; }

        public Point(int x, int y)
        {
            X = x;
            Y = y;
        }

        public override string ToString()
        {
            return $"{X}, {Y}";
        }
    }

    internal static class Program
    {
        public static void PrintLine(this Point point)
        {
            Console.WriteLine(point);
        }

        private static void Main(string[] args)
        {
        }
    }
}

PascalABC.NET:

uses System;

type
  PointT = record
    public auto property X: integer;
    public auto property Y: integer;
    
    constructor(x, y: integer);
    begin
      self.X := x;
      self.Y := y;
    end;
    
    function ToString(): string; override := $'{X}, {Y}';
  end;

procedure PrintLine(self: PointT); extensionmethod := Writeln(self);

begin
end.

Пример применения: гибкое расширение функциональности встроенных типов без необходимости вносить изменения в исходный код.

Операторы расширения

C#: на данный момент указанной возможности нет в C#, элегантного решения проблемы не существует для структур, однако для классов можно расширить функциональность базового класса, унаследовавшись от него и определив необходимые операторы.

PascalABC.NET:

uses System;

type
  PointT = record
    public auto property X: integer;
    public auto property Y: integer;
    
    constructor(x, y: integer);
    begin
      self.X := x;
      self.Y := y;
    end;
    
    function Sum(other: PointT) := new PointT(X + other.X, Y + other.Y);
    
    function ToString(): string; override := $'{X}, {Y}';
  end;

procedure PrintLine(self: PointT); extensionmethod := Writeln(self);

function operator+(left, right: PointT); extensionmethod := left.Sum(right);

begin
end.

Пример использования: сокращение записи операций добавления и удаления элементов из коллекций (например, + для массивов из PABCSystem).

2 сообщения перенесены в тему Сравнение C# и PascalABC.NET - Обсуждение