csharp
MacGreener C#

Переписал МакГринер с Си на Си#. Основной код
Весь код разбит, преимущественно, на три класса — основной класс, где выполняется приложение, класс IOKit — низкоуровневые и чуть более высокоуровневые биндинги для библиотек МакОСи и IOKitMotionSensor — ещё более высокоуровневая обёртка над куском кода для опроса датчика.
Есть ещё два вспомогательных класса — IOKitException, класс кидаемых исключений и IOKitObject — класс всех ресурсов, которые требуется высвобождать (он следит за своевременным их высвобождением при помощи блока using).
Не знаю какую версию я буду дальше развивать (и буду ли), но версия на Си# более прожорлива —
Хорошо, что мой братишка давно программирует на этом языке, с его консультациями в некоторых тонкостях удаётся разобраться быстрее.
Первые эксперименты с C#
Поучился обращаться к динамическим библиотекам «Мака» (dylib)
using System;
using System.Runtime.InteropServices;
using MonoMac;
using MonoMac.CoreFoundation;
using MonoMac.ObjCRuntime;
namespace MacGreenerFragment
{
class SleepAwake
{
[DllImport ("IOKit", CharSet = CharSet.Ansi)]
static extern int IORegistryEntryFromPath (IntPtr masterPort, string path);
[DllImport ("IOKit")]
static extern void IOObjectRelease (int @object);
[DllImport ("IOKit")]
static extern void IORegistryEntrySetCFProperty(int entry, IntPtr propertyName, IntPtr property);
static void macSleepAwake(bool sleep)
{
var handle = Dlfcn.dlopen (Constants.CoreFoundationLibrary, 0);
IntPtr True = Dlfcn.GetIntPtr (handle, "kCFBooleanTrue");
IntPtr False = Dlfcn.GetIntPtr (handle, "kCFBooleanFalse");
int r = IORegistryEntryFromPath(IntPtr.Zero, "IOService:/IOResources/IODisplayWrangler");
if (r != 0) {
IORegistryEntrySetCFProperty(r, ((CFString)"IORequestIdle").Handle, sleep ? True : False);
IOObjectRelease(r);
}
}
}
}На Си это 11 строк.
Шутка про женщин на C#
Придумалась шутка про женщин на языке
class Woman {
public static bool operator true (Woman question) {
return false;
}
public static bool operator false (Woman question) {
return false;
}
}Идентификаторы в C#
Я тут

Обратите внимание на строку 9, тут любопытно, я встречал языки, где в качестве имён переменных можно использовать символы Юникода (тот же ПХП), а тут, мало того, можно писать юникодные символы с использованием
Например, у меня, в качестве имени переменной, используется символ «усмехающееся кошачье лицо со смешинками в глазах» (не всем видно будет — ?). Со вторым идентификатором ещё интереснее.
Если вам нужно использовать в качестве идентификатора зарезервированное слово (ну вот надо, а максимально подходящее английское слово является зарезервированным), можно предварить его «собачкой» и в таком виде использовать (см. строку 10).
Программа выше компилируется и выполняется без ошибок.
А вот вещь по которой я скучал: фигурные скобки создают локальную область видимости (как в Перле), правда я не могу определить переменную в этом блоке, которая уже есть в локальном блоке выше, причём только до замыкания, удивительное правило.
Ну да ладно, в общем, вот такой код не скомпилируется, будет ошибка в последней строке, сообщающая об отсутствие переменной @string:
{
string @string = @"string ""string""";
Console.WriteLine (@string.Insert (1, "tt"));
}
Console.WriteLine (@string); // ошибка!Вещь, с которой не ожидал столкнуться — автоматическое приведение типов. Я
byte байтраз = 3, байтдва = 5;
// строка кода ниже выведет System.Int32 (а не System.Byte, как я ожидал)
// арифметические операции определены только для типов int и больше,
// поэтому произойдёт преобразование типов
Console.WriteLine ((байтраз + байтдва).GetType());
Console.WriteLine ("Первый байт равен: " + байтраз); // строки спокойно складываются с числамиЕщё интересная вещь — отключение проверки переполнения (в нормальной ситуации вызовется исключение), видимо для совместимости с сишным поведением:
int int1, int2;
unchecked {
int1 = int2 = System.Int32.MaxValue;
int1 += int2;
}
Console.WriteLine (int1); // выведет -2