Useful C# Features (or “Cool Things You Didn’t Know You Could Use in Unity”)

1. Tuples & Discards!

Tuples is something more dynamic languages like JavaScript have been holding over the more static languages for a while. It allows you to do more with less action (higher level ones, that is). While tuples have existed in C# before as a class of their own, they are now getting a proper implementation. It basically makes a complex variable/object without having to predefine it using a class or a struct.

var alphabetStart = (Alpha: "a", Beta: "b");
Console.WriteLine($"{alphabetStart.Alpha}, {alphabetStart.Beta}");

You can even use it to return more than one element from a method(!!!). Unfortunately, the Unity editor doesn’t support handling those kinds of returns yet but they are still useful inside your scripts.

Discards are those underscores you see in the example below. It allows you to deconstruct a tuple and discard the data you don’t want, only keeping what you actually need in its own named variable.

using System;

public class Example
    public string NewYorkCityName
            var (_, name, _) = QueryCityData("New York City");
            return name;

    private static (string name, int pop, double size) QueryCityData(string name)
        if (name == "New York City")
        { return (name, 8175133, 468.48); }

        return ("", 0, 0);

2. Pattern Matching!

Pattern matching allows you to test a runtime type in an if or switch statement and then convert it to that specific type all in a single statement!

if (input is int count)
{ sum += count; }

It also increases the power of switch, allowing you to do a lot more with less and create much more complex testing blocks.

public static int SumPositiveNumbers(IEnumerable<object> sequence)
    int sum = 0;
    foreach (var i in sequence)
        switch (i)
            case 0: break;
            case IEnumerable<int> childSequence:
                foreach(var item in childSequence)
                { sum += (item > 0) ? item : 0; }
            case int n when n > 0: sum += n; break;
            case null: throw new NullReferenceException("Null found in sequence");
            default: throw new InvalidOperationException("Unrecognized type");
    return sum;

3. Local functions

Local functions is currently one of my favorite features in C#. You could already create functions inside functions by assigning a block into an Action or Func variable but now you can just define an anonymous function and not worry about what returns or not returns a value or where exactly you defined which variable. So, if you need a complex block or calling the same function multiple times but you don’t want it available outside, Local Functions are here for you.

private static string GetText(string path, string filename)
     string AppendPathSeparator(string filepath)
     { return filepath.EndsWith(@"\") ? filepath : filepath + @"\"; }

     var reader = File.OpenText($"{AppendPathSeparator(path)}{filename}");
     var text = reader.ReadToEnd();
     return text;

4. Switch Expressions!

You can now rephrase your Switch blocks into something much nicer and readable.

public static RGBColor FromRainbow(Rainbow colorBand) =>
    colorBand switch
        Rainbow.Red    => new RGBColor(0xFF, 0x00, 0x00),
        Rainbow.Orange => new RGBColor(0xFF, 0x7F, 0x00),
        Rainbow.Yellow => new RGBColor(0xFF, 0xFF, 0x00),
        Rainbow.Green  => new RGBColor(0x00, 0xFF, 0x00),
        Rainbow.Blue   => new RGBColor(0x00, 0x00, 0xFF),
        Rainbow.Indigo => new RGBColor(0x4B, 0x00, 0x82),
        Rainbow.Violet => new RGBColor(0x94, 0x00, 0xD3),
        _              => throw new ArgumentException(message: "invalid enum value", paramName: nameof(colorBand)),

5. Property Patterns

This is another wonderful extension to the switch statement allowing you to switch on a structure and get output depending on its internal properties rather easily.

public static decimal ComputeSalesTax(Address location, decimal salePrice) =>
    location switch
        { State: "WA" } => salePrice * 0.06M,
        { State: "MN" } => salePrice * 0.075M,
        { State: "MI" } => salePrice * 0.05M,
        // other cases removed for brevity...
        _ => 0M

6. Tuple Patterns

This is another cool extension to the switch statement, allowing you to match a case based on individual items inside a tuple breakdown.

public static string RockPaperScissors(string first, string second)
    => (first, second) switch
        ("rock", "paper") => "rock is covered by paper. Paper wins.",
        ("rock", "scissors") => "rock breaks scissors. Rock wins.",
        ("paper", "rock") => "paper covers rock. Paper wins.",
        ("paper", "scissors") => "paper is cut by scissors. Scissors wins.",
        ("scissors", "rock") => "scissors is broken by rock. Rock wins.",
        ("scissors", "paper") => "scissors cuts paper. Scissors wins.",
        (_, _) => "tie"

7. Using Declarations

One of the really nice things in C# over C and C++ is that it is a managed language. Yes, there are performance differences (which Unity has almost 100% taken care of) but it is a huge load of responsibility off the developer. The Using declaration is a great way to take advantage of it. When you need to open a file or create a web request but just for a short time and you want to dispose of it properly… you can go through the whole rigmarole or just enclose the code in a Using block that takes care of everything for you.

static int WriteLinesToFile(IEnumerable<string> lines)
    using (var file = new System.IO.StreamWriter("WriteLines2.txt"))
        int skippedLines = 0;
        foreach (string line in lines)
            if (!line.Contains("Second"))
            { file.WriteLine(line); }
            { skippedLines++; }
        return skippedLines;
    } // file is disposed here

8. Indices and Ranges

First of all, you can now define a range in C#.

Range phrase = 1..4;

And you can use those numbers or that Range to access a sub-range or a sub-group of another variable. However, be careful because range accessors are beginning inclusive and ending exclusive.

var words = new string[] { "The", "quick", "brown", "fox", "jumped", "over", "the", "lazy", "dog" };

var quickBrownFox = words[1..4]; // "quick", "brown", "fox" and no "jumped"

var lazyDog = words[^2..^0];
 // The from-end index accessor. ^0 is the end and not included
var allWords = words[..]; // contains "The" through "dog".
var firstPhrase = words[..4]; // contains "The" through "fox"
var lastPhrase = words[6..]; // contains "the", "lazy" and "dog"
var text = words[phrase]; // is like quickBrownFox

9. Null Coalescing Assignment

The Null Coalescing Operators are some of my favorite features in new C#. It allows you to check for Nullls and then do things accordingly. The null-coalescing assignment operator checks if the left side is null. If it isn’t, it’s returned. If it is, the right side is assigned to it and then it’s returned. It’s a great way to do lazy resource assignment and/or creation. 

List<int> numbers = null;
int? i = null;

numbers ??= new List<int>();
numbers.Add(i ??= 17);
numbers.Add(i ??= 20);

Console.WriteLine(string.Join(" ", numbers));  // output: 17 17
Console.WriteLine(i);  // output: 17

Posted in IT, Life, Programming by with no comments yet.

Portugal just became nicer to employees

Portugal recently passed a law they fondly call “Right to Rest”.

It contains various measures to help employees have a better work-life balance such as the ability to work remotely when you need to take care of a child or companies contributing to household bills when an employee is working remotely a lot. But the nicest thing about it is indeed the ban on contacting employees after work hours. I’m guessing there is a stipulation about emergencies or people like server administrators and doctors who are supposed to be on call but the fact it’s enshrined in law is just amazing.

Kinda makes me want to move to Portugal. :)

Posted in High-Tech, IT, Less Interesting News, Practice, Thinking Out Loud by with no comments yet.

Temp Logs into Documentation

Here’s an idea I had while writing a server application I needed to test on a remote computer with limited debugging abilities…

I insert debug logs, temporary logs, before and/or after important sections of flow so I could see in the console what is going on and what is failing. But I wouldn’t want them there when the app rolls into production.

And then I thought, people hate writing in-line documentation but it’s quite important. And here I have all these debug logs explaining what is going on. So, instead of deleting them, comment them out. Then I have them for later, if I want, and they pretty much function like in-line documentation.


Posted in IT, Life, Practice, Programming, Thinking Out Loud, Work by with comments disabled.

קצת גאה בעצמי

היה לי יום טוב היום.

זאת אומרת, הוא התחיל בזה שחשבתי שיש לי שעון ואז גיליתי שיש לי אבל, משום מה, הוא לא העיר אותי. אז היפלתי על מעין לטפל במוצארט בבוקר ומיהרתי החוצה.

סיימתי עוד פרויקט בעבודה והראיתי אותו לבוס. קיבלתי כמה תיקונים עליהם אני עדיין עובד. בסדר. אבל אני כן גאה בזה שבשביל להשיג כל מיני אפקטים הייתי צריך להשתמש בחבילת תוכנה שכולם משתמשים בה אבל לא הצלחתי לגרום לה לעשות בדיוק מה שאני רוצה. כששאלתי, התשובה שקיבלתי היא ‘יש דרך אבל היא לא כל כך טובה אבל ככה כולם עושים’. אז לא רציתי לעשות את זה ככה. כתבתי גרסה משל עצמי.

לא שכתבתי ספריה פופלארית מאפס אבל, אם היא מסוגלת לעשות א’ ועד ת’, אני צריך ח’ וחצי, אולי שני ח’. והיא לא הייתה יכולה לתת לי את זה. אז לקחתי שעה וחצי וכתבתי משהו שעושה שלושה וחצי ח’, כדי שיהיה וזה כבר היה על הדרך.

וחזרתי הביתה ועשיתי התעמלות. יום בטן. לא הצלחתי להגיע לגבול הנוכחי אבל הצלחתי לסיים את הקודם בהצלחה. לפחות זה. אני כבר מרגיש יותר טוב. בהחלט יותר ערני ואנרגטי.


Posted in IT, Life, Me, Programming by with comments disabled.

עבודה חדשה

התחלתי עבודה חדשה. מדובר בחברה נחמדה בתל-אביב. בינתיים, נראה שהאנשים שם מאוד נחמדים. לקחו אותי בתור מישהו שמנוסה עם Unity בשביל לעשות קצת מחקר וניסויים ולפתח תחום שהם רוצים להיכנס אליו. אני מאוד אוהב את האווירה כי אני הראשון ויכול להגדיר את הסגנון. וגם לא מלחיצים אותי ומתייחסים מאוד טוב לזמן שלוקח לעשות דברים. וזה גם נותן לי די והותר זמן לעסוק בפרויקטים הפרטיים שלי.

אז כרגע אני בעיקר מנסה להרשים אותם כמה שאני יכול בתקווה שזאת תהיה מערכת יחסים ארוכת טווח.

Posted in IT, Life, Work by with comments disabled.

איך אפשר להתקין חלונות מחדש בקלות

לאחרונה המחשב שלי התחיל לעשות בעיות. זה התחיל עם התקנה שנדפקה ועל הדרך גם שיבשה לי את ה-Defender והמשיך לכך ש-Visual Studio ו-Unity הפסיקו לשתף פעולה. אז החלטתי להתקין מחדש. אז אני פה כדי להגיד שנכון, לכל המאוחר, לחלונות 10, להביא את המערכת למצב של כאילו כרגע הפעלת אותה בפעם הראשונה, זה ממש קל. להלן, בתמונות.


Posted in IT, Practice by with comments disabled.

The ISAs. They Are Not Here Yet.

Writing, the printing press, industrialisation, the microchip, the internet.

There are several inventions that have sliced history at the point of creation, that changed the world so much that you can discuss civilisation has ‘before this’ and ‘after this’.

I expect ISA, Intelligent Software Agents, to be the next one in that list.

What is an ISA? For those who don’t know, an ISA is like a software butler. Not a robot you order around the house but an ethereal ghost in the machine that can follow general instructions and perform tasks for you. Basically, take a general AI and give it a couple of white gloves and a double tail jacket.

And while some of you might be thinking we have Siri and S Voice, the Google Assistant and Alexa. But these are an OK start. We are not at the goal post yet. While I might be able to tell a properly equipped smart home to set my AC to certain temperature or start my coffee maker, I can’t tell a digital assistant to sort my news.

This is my benchmark now. Can we have a software agent that sorts my news?

What do I mean: I have a news reader on my phone that scrapes certain feeds I set it too. Sometimes I read my news while doing something else, sometimes I want to focus on that, sometimes I listen to it as I walk the dog and have distractions and sometimes I listen to it on my bicycle and want something more intense.

Currently I sort it by feeds and categories which is the only way I can. And I try to number categories by rate of intensity. So I read it in ascending order and listen in descending order. But if I had a proper ISA, I could tell it to put the short Slashdot articles, the ‘list of things you should know’ articles, the articles I might be interested in the title of or the first couple of paragraphs, in the light category.  I would tell it to put the detailed, statistics heavy articles with lots of reference images in the ‘things I really need to sit down and read’ category. I would tell it to put the long analyses in the ‘listen when out and about’ category. And I would tell it to put APOD and Digital Blasphemy and articles that are just video references in the ‘check this when on a PC’ category.

But we can’t do that yet. When we could, that would be the shit!

Posted in IT, Practice, Thinking Out Loud by with 6 comments.

Fuck You, Xamarin

After messing around with tutorials and trying to put something together for about a month and finally running into huge building/libraries/references issues that I couldn’t solve for a few days, I decided to quit Xamarin development. At least, for now.

Even planned as a simple 2D application, I’m willing to accept the splash screen and loading times so I can do this handily in Unity GUI. And I know it will compile very easily to Android and, slightly less easily, to iOS. It will definitely be quicker and easier to build.

Posted in IT, Life, Programming by with comments disabled.

What happened to RSS? 

אני זוכר שבעבר, RSS היה משהו. לכל אתר שמתעדכן קבוע ומכבד את עצמו היה RSS. עדיין, לגדולים, יש אבל… זה כאילו שלאנשים פחות אכפת.

אני צריך לעדכן את הרססים של IGN כל כמה חודשים. אני צריך להכריח את YouTube בשביל לקבל רסס. יש אתרים שאנשים פרטיים הקימו להם רסס לא רשמי. ויש לי רססים שלפעמים פשוט נשברים בלי הסבר.

אני קצת מתגעגע לזמן בו הקמתי את הבלוג הזה. הכוונה שלי הייתה שיהיה לבן אדם אתר שבו הוא יכתוב מה שעולה לו בראש וכל מה שבה לו להגיד, הבמה הפרטית שלו, וכל מי שמעניין אותו, ירשם לרסס ויקבל עדכון כשיש במקום שנוח לו.

ומשום מה, פרחו כל הרשתות החברתיות והרעיון הזה הלך לאיבוד.

אני קצת חושש ממה שאולי יקרה לרסס. כי, לדעתי, זאת עדיין הדרך הכי טובה לבן אדם הקטן להתממשק עם זרנוק המידע שהוא האינטרנט.

Posted in IT, Practice, Thinking Out Loud by with 1 comment.

An Attempt at Change

נחתנו אתמול ב-5:30 בבוקר. בגלל שקניתי שני בקבוקי סיידר, היינו צריכים להכניס תיק לבטן המטוס. זאת אומרת, גם לחכות עד שיוציאו אותו משם במקום מיד לצאת החוצה. שזה מבאס. אבל לא נורא. הצלחנו לתפוס את הרכבת של 6:00 ולהגיע הביתה בסדר גמור. זאת אומרת, מעין הייתה דיי גמורה. אבל אחד היתרונות של שינה פוליפאזית היא שאחרי תנומות באות והולכות במטוס, מוקדם בבוקר הייתי סבבה.

אז קפצנו אל יערה לאסוף את מוצארט. האיחוד היה מרגש. לא יכולנו להישאר יותר מדי כי מיהרנו אז אמרנו שלום, תודה ולהתראות ויצאנו לדרך שוב. וכשהגענו הביתה, היה בערך מספיק זמן בשביל להתרחץ ולצאת שוב לדרך. כי היה לי ראיון אם ראש הצוות VR/AR של קופמדיה, איפה שעמית ורומן עובדים.

אני חשבתי שמדובר בראיון “שלום, שלום” ולא ציפיתי למרכיב טכני. אם כן הייתי מצפה אז הייתי פותח את הקוד של הפרויקט שלי שוב ונזכר מה עשיתי שם. כנראה שלא אצליח למצוא את השינויים שעשיתי לקוד של Oculus אבל לפחות את הרעיון הכללי והמימוש של המשחק עצמו הייתי יכול לזכור. לכן, קצת השתנקתי כששאלו אותי שאלות עליו אבל ניסיתי לענות כפי יכולתי. ואני בדרך כלל נתקע כששואלים אותי שאלות שנראות לי מאוד פשוטות. כי אם שואלים דבר כמו “איך מחשבים אורך של וקטור תלת ממדי?” אני מתחיל לתהות אם אני זוכר את המתמטיקה שלי כמו שצריך. כי (x^2+y^2+z^2)^(1/3), לא? אבל אני מקווה שהעברתי רושם מספיק טוב ושהם לא חושבים שאני אידיוט. יהיה ממש מגניב ללכת לעבוד שם.

וחשבתי על זה עוד קצת היום במהלך מסיבת הפורים שלא ממש היה לי כוח להשתתף בה. אני עייף? אני פשוט בקצה החבל? האם שנתיים וחצי זה המקסימום שאני מסוגל כרגע להשקיע בפרויקט אחד? כי אני באמת מוצא שפחות אכפת לי. זאת אומרת, אכפת לי שהמשחק יצליח ושהחברה תצליח אבל אין לי כבר כוח להתקטנן על מימוש או לוודא שדברים נעשים כמו שצריך. אני יותר בסדר עם זה שאנשים יכשלו לבד ויראו שדברים נשברים ולא לעצור אותם לפניי.

אולי מה שאני צריך זה פשוט הפסקה רצינית.

Posted in IT, Life, Work by with comments disabled.