The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 2,422 other followers

Archive for the ‘C#’ Category

Methods on enums by using extension methods: Unity sample MonoBehaviour explaining how to associate simple strings with enums.

Posted by jpluimers on 2021/07/29

Reminder to self (as I keep forgetting how versatile extension methods can be):

[WayBack] Mark Pintar sur Twitter : “The nice thing about extension methods is one can add it to most types. Even works of int, float and other primitive types… “

An interesting way of allowing methods on enumerated types is by using extension methods: [WayBack] Unity sample MonoBehaviour explaining how to associate simple strings with enums. · GitHub.

A more elaborate example from [WayBack] NoraGrace-Chess/Position.cs at master · ericoldre/NoraGrace-Chess · GitHub is below the fold.

Via:

 

using System;
using System.ComponentModel;
using UnityEngine;

public class EnumDescription : MonoBehaviour
{
    public enum PlayerState
    {
        Unknown,
        [Description("Alive and kicking")]
        Alive,
        [Description("Dead as a duck")]
        Dead
    }

    // Start is called before the first frame update
    void Start()
    {
        var state = PlayerState.Dead;
        Debug.Log("Player is " + state.GetDescription());
    }
}

public static class EnumExtensions
{
    public static string GetDescription(this Enum value)
    {
        var type = value.GetType();
        var name = Enum.GetName(type, value);
        if (name != null)
        {
            var field = type.GetField(name);
            if (field != null)
            {
                if (Attribute.GetCustomAttribute(field,
                  typeof(DescriptionAttribute)) is DescriptionAttribute attr)
                    return attr.Description;
            }
        }
        return name;
    }
}

Read the rest of this entry »

Posted in .NET, C#, Development, Software Development | Leave a Comment »

c# – Algorithm to check whether a certain hour falls into a given time period – Stack Overflow

Posted by jpluimers on 2021/07/15

For my link archive: [WayBack] c# – Algorithm to check whether a certain hour falls into a given time period – Stack Overflow answered by [WayBack] kennytm:

Assume you only have the time and not the date.

if end_time >= start_time:
    return start_time <= current_time <= end_time
else:
    return start_time <= current_time or current_time <= end_time

I totally agree with this comment:

This is brilliant! Thanks a lot. – Martin Dimitrov [WayBack]

I love it when algorithms are simple and elegant.

It reminded me of another scheduling related algorithm: [WayBack] Activity Selection Problem | Greedy Algo-1 – GeeksforGeeks

–jeroen

 

Posted in .NET, Algorithms, C#, Development, Software Development | Leave a Comment »

“No mapping for the Unicode character exists in the target multi-byte code page”

Posted by jpluimers on 2021/06/24

Usually when I see this error [Wayback] “No mapping for the Unicode character exists in the target multi-byte code page” – Google Search, it is in legacy code that uses string buffers where decoding or decompressing data into.

This is almost always wrong no matter what kind of data you use, as it will depend in your string encoding.

I have seen it happen especially in these cases:

  • base64 decoding from string to string (solution: decode from a string stream into a binary stream, then post-process from there)
  • zip or zlib decompress from binary stream to string stream, then reading the string stream (solution: decompress from binary stream to binary stream, then post-process from there)

Most cases I encountered were in Delphi and C code, but surprisingly I also bumped into C# exhibiting this behaviour.

I’m not alone, just see these examples from the above Google search:

–jeroen

Posted in .NET, base64, C, C#, C++, Delphi, Development, Encoding, Software Development, Unicode | Leave a Comment »

Delphi compile time assertions

Posted by jpluimers on 2021/02/24

My post on Delphi intrinsic functions that evaluate to consts as a step up to Delphi compile time assertions.

This is a corner case of Delphi language use, which can come in very handy when your code is changed in the future, and you want to be prepared to ensure that some changes do not violate some predefined boundaries.

Hopefully a future post will elaborate a bit more on actual usage, but for now, lets first show some examples, then some other languages that have a richer set of compile time assertions.

My original goal was to see if I could come up with a mechanism that allowed for better validation of generic types because Delphi generic constraints – still – are quite limited: Delphi Constraints in Generics – RAD Studio XE documentation wiki, so limiting or verifying the aspects of the concrete type often cannot be done by constraints.

C# had a similar limitation for constraining to enum, which finally got added some 13 years after adding generics, in 2018: [WayBack] Unmanaged, delegate and enum type constraints – C# 7.3 in Rider and ReSharper – .NET Tools Blog.NET Tools Blog.

Let’s start simple:

const
  // forbidden const values to check compile time assert:
  A = 0;
  B = 1;
  C = -1;
  // The below expressions all each generate a "[dcc32 Error] E2098 Division by zero" (so multiple errors in one compile)
  // Asserting at compile time using boolean expressions:
  BooleanAssertAIsNotZero =  1 div Ord(A <> 0);
  BooleanAssertBIsNotOne = 1 div Ord(B <> 1);
  // Asserting at compile time using numeric expressions:
  AssertAIsNotZero = 1 div A;
  AssertBIsNotOne =  1 div (B - 1);
  AssertBIsNotAbsOne =  1 div (Abs(B) - 1);
  AssertCIsNotAbsOne =  1 div (Abs(C) - 1);

This is all centered around generating a compile time error "[dcc32 Error] E2098 Division by zero", of which multiple can occur in one compile go (after compilation, the cursor focus will be at the first error) and which has been in the language for a very long time [WayBack] E2098: Division by zero.

The conversion of Boolean to Integer is done using Ord, a very powerful compile time intrinsic that evaluates to a constant.

You can use this for other intrinsics as well, for example:

type
  TDigits = 0..9;

const
  DigitsAreInteger = GetTypeKind(TDigits) = tkInteger;
  DigitsAreIntegerIsTrue = 1 div Ord(DigitsAreInteger);
  DigitsAreEnumeration = GetTypeKind(TDigits) = tkEnumeration; // compiles fine
  DigitsAreEnumerationIsTrue = 1 div Ord(DigitsAreEnumeration); // [dcc32 Error] E2098 Division by zero

The above learns that integer subranges are not enumerations, but stay integers.

You can now extend this to check longer boolean expressions, for instance to check if a record size matches certain criteria. For this we create records having zero to four bytes in size (yes, you can have empty record in Delphi, it in fact the only data structure that can be zero bytes in length, though the documentation [WayBack] Structured Types: record types does not state this is in fact possible ), then validate the sizes:

type
  TRecord0 = record
  end;

  TRecord1 = packed record
    FByte0: Byte;
  end;

  TRecord2 = packed record
    FByte0: Byte;
    FByte1: Byte;
  end;

  TRecord3 = packed record
    FByte0: Byte;
    FByte1: Byte;
    FByte2: Byte;
  end;

  TRecord4 = packed record
    FByte0: Byte;
    FByte1: Byte;
    FByte2: Byte;
    FByte3: Byte;
  end;

const
  AssertTRecord0SizeOf0 = 1 div Ord(SizeOf(TRecord0) = 0); // When expression is false: [dcc32 Error] E2098 Division by zero
  AssertTRecord0SizeOf1 = 1 div Ord(SizeOf(TRecord1) = 1); // When expression is false: [dcc32 Error] E2098 Division by zero
  AssertTRecord0SizeOf2 = 1 div Ord(SizeOf(TRecord2) = 2); // When expression is false: [dcc32 Error] E2098 Division by zero
  AssertTRecord0SizeOf3 = 1 div Ord(SizeOf(TRecord3) = 3); // When expression is false: [dcc32 Error] E2098 Division by zero
  AssertTRecord0SizeOf4 = 1 div Ord(SizeOf(TRecord4) = 4); // When expression is false: [dcc32 Error] E2098 Division by zero
  AssertTRecord0SizeOfMultipleOf4 = 1 div Ord(SizeOf(TRecord0) mod 4 = 0); // When expression is false: [dcc32 Error] E2098 Division by zero
  AssertTRecord4SizeOfMultipleOf4 = 1 div Ord(SizeOf(TRecord4) mod 4 = 0); // When expression is false: [dcc32 Error] E2098 Division by zero
  AssertTRecord0SizeOfMultipleOf4AndGreaterThan0 = 1 div Ord((SizeOf(TRecord0) mod 4 = 0) and (SizeOf(TRecord0) > 0)); // When expression is false: [dcc32 Error] E2098 Division by zero
  AssertTRecord4SizeOfMultipleOf4AndGreaterThan0 = 1 div Ord((SizeOf(TRecord4) mod 4 = 0) and (SizeOf(TRecord4) > 0)); // When expression is false: [dcc32 Error] E2098 Division by zero

That’s how far I got in my first experiments using this mechanism. Hopefully it gave you some inspiration too, so I welcome any usages you made with it.

Inline use of intrinsics can lead to no generated code at all

Since Delphi has no macro language, you cannot create your own intrinsic functions that evaluate to const. You could use a pre-processor though, as described in [WayBack] How to write Delphi compile-time functions – Stack Overflow.

The answer by Johan there however mentions clever use of in-line functions that do not generate any code at all (so effectively evaluate to a const). More on that in a future post.

Compile time assertions in other languages

Many languages support a form of [WayBack] Compile-time calculation – Rosetta Code. If such a language can errors out on compiling such a calculation, then you can have compile time assertions.

Compile time assertions are very much used in C and C++, where they are often called static assertions. Often they depend on macros, but C11 (C standard revision 11) has it built-in.

Since I also do quite a bit of .NET: [WayBack] Can C# Provide a static_assert? – Stack Overflow

Some links on how they work in C and C++, and what you can do with them:

–jeroen

Posted in .NET, C, C#, C++, Conference Topics, Conferences, Delphi, Development, Event, Software Development | Leave a Comment »

.NET: interfaces that inherit from multiple base interfaces

Posted by jpluimers on 2020/12/03

For my link archive:

Read the rest of this entry »

Posted in .NET, C#, Delphi, Development, Software Development | Leave a Comment »

 
%d bloggers like this: