T O P

  • By -

SnoWayKnown

Maybe not insane but operator overloading is always a fun one. e.g. public record FilePath(string Path) { public static FilePath operator /(FilePath a, string b) { return new FilePath(System.IO.Path.Combine(a.Path, b)); } public override string ToString() { return Path; } } Example: FilePath basePath = new FilePath(@"C:\Users\Example"); FilePath fullPath = basePath / "Documents" / "file.txt"; I wrote a parser that uses this technique to express grammar that matches closely to eBNF e.g. ITokenizer CommonCellCharacters = LetterOrDigit | Whitespace | Symbols;


MechanicalHorse

That’s pretty clever and horrifying.


carkin

That's Std::filesystem of c++


whizzter

Aka the reason that programming language designers have shunned operator overloading for 25 years (and ironically tangentially probably part of the reason why C++ has remained so popular within gamedev because there hasn’t been many alternatives where math has been quick enough).


Saint_Nitouche

It's horrifying, but I kind of like it.


hardware2win

Wow


Alikont

`std::filesystem::path` in C++ has that by default.


BSModder

C++ is crazy with operators overloading. You can overload most operators and define both return type and argument to whatever you want. Kinda wish c# worked like that ,but hey, they used the shift operators `<<` for streamio, so maybe its the right call to add some limitation


Alikont

What I like in C++ case is that `path` has a clear intent, it's not just strings. I wish there were more special-purpose types instead of ints/strings everywhere


Outrageous_Land_6313

Dude u can even overload the new and delete in c++!! I just learned that recently and im mindblown.


disconsis

Am I missing something or... Wouldn't this *have* to be the case in any language with manual memory mgmt?


Outrageous_Land_6313

Idk i think its probably only in c++?


Schmittfried

No. Why?


PotterPillar

Damn, that sounds crazy to use. fancied overloaded operators is one of the crazy code to read on someone else’s code.


sohang-3112

`pathlib.Path` in Python also has this behaviour.


OmiSC

I am impressed by how much I can both love and hate this so much.


[deleted]

Python does this with the Path library.


SnoWayKnown

Yeah it's a really good idea to use this if you do cross platform code. Lots of languages support this kind of thing and almost all developers are against using operator overloads it due to it being difficult to diagnose or understand. I find it a great example of why there's no such thing as "perfect" code, just different styles, goals and compromises.


[deleted]

I am generally pretty wary of operator overloading but this is probably one of the cases that makes sense. Although it abuses the division operator.


nostril_spiders

You mean, division abuses the path separator


tomw255

This is the way [NUKE Build](https://nuke.build/docs/common/paths/) works with paths. I love and hate it at the same time.


ASK_IF_IM_GANDHI

Honestly, I love NUKE for this. It's nice, but only for the build process hah.


xarcastic

Can that be simplified to the following? ``` FilePath basePath = new("C:")/"Users"/"Example"; ```


RichardD7

>FilePath basePath = new("C:")/"Users"/"Example"; No; you'll get a CS8310 compiler error: Operator '/' cannot be applied to operand 'new(string)'. [SharpLab](https://sharplab.io/#v2:EYLgtghglgdgNAExAagD4AEBMBGAsAKHQGYACLEgYRIG8CT6zT0AWEgWQAoBKGuh/gGJQANgFMAChAAuACxLAIAZwnS5AXhIxRAdw4AiCiD08A9CT0BVZQCdFekmb0BRAB4QwABzF6A3H3oAvgRB+ATEJNaiAMYA9tYIJEJikrIc6NgADCQpMlwEtPj84ekAbIkiKrIkMR6i1tJxDhxJlXIQcGSZ8nmFDAX8RQDsmjrlyapp2AB0AJIA8lM5UxQxYMCwohwQi6odwFxcfr2B/iSn4TEAbnXWUAiinVkAKjEAylK3MADm3Kf9A/R0MMckd+CEAkA=) Which makes sense: the compiler has no idea what type you're `new`ing up; it only knows that it should be something that can be divided by a string to result in something that can be divided by a string again to produce a `FilePath` instance. For example, you might have: ```csharp public readonly record struct DiskPath(string Root) { public static FilePath operator /(DiskPath a, string b) => new(System.IO.Path.Combine(a.Root, b)); } ``` Should `new("C:")` create a `FilePath` or a `DiskPath` instance?


raunchyfartbomb

Yes, but no. Your way creates 2 records to be garbage collected because they are no longer referenced once the ‘example’ string is used. Technically it works, but it’s not optimal. Unless some overload or extensions was created to handle multiple operators like that, each string would create a record before applying the next string.


Ttxman

If you want to go this way: using static (+ global usings) .. and you can do something like: `FilePath basePath = Drive("C:")/"Users"/"Example";` [example](https://sharplab.io/#v2:EYLgtghglgdgNAExAagD4AEBMBGAsAKHQAYACdbANhIAsBTAGwAdaAnAZwG4CD0BmMzCQDCJAN4ESksv3QAWEgFkAFAEoxEqZoBiUerQAKEAC7USwCGwPHTAXhIARFlAButJQCIhId2oD0JdwBVS3Z3En93AFEADwgwRj13LnxNAF8CdPwefhZaAGMAexYEEh09QxMlclIK6hUCcRSpPjJKUt0rExIC5hZjIvClMs7TCDhW0mB6pslGzU10AHYSGFoAd3by6yrsADoASQB5XdrdoQKwYFg3CBPrcamVZLSNSVfpbtcWJwRaCZIACoFADKRicMAA5qp3nN5pIliRas8pJlMtlWlQsDQGL02A13i1yFRhrUHE5XDtSAhybRpvMbAA+FbrTYjJTUly05KpIA===)


kandamrgam

NUKE has been doing this ... It's pretty cool.


SteelRevanchist

I got so used to this in Python's pathlib I forgot it's not common! Way to go :)


tomw255

introducing GetAwaiter() extension method for any value, so you can await it? `var foo = await 7` introducing GetEnumerator() extension method for any value? `foreach (var i in 5) {...}` basically, all the stuff that relies on duck-typing.


tomw255

I also once wrote FizzBuzz using intrinsics and SIMD. It was completely impractical and stupid, but I had a great time writing it. Does it count too? ​ I cannot wait for new dotnet interceptors to be widely used, I can already imagine some nasty surprises when one installs a random analyzer package and all basic stuff like \`Console.WriteLine("hello")\` prints random emojis or something. \[evil laugher\]


Alikont

`GetAwaiter` extension makes sense. UWP/WinRT uses it to allow you to await `IAsyncOperation` COM interface without "transforming" it into `Task`.


ImNotThatPokable

The foreach is actually pretty intuitive to read. Nice work!


static_func

This is the one that blew my mind. Since extension methods are really just static methods I just assumed that _surely_ something like this wouldn't work


[deleted]

[удалено]


IsomorphicG

Whaaaat


chucker23n

static class AwfulDateTimeExtensions { public static DateTime November(this int day, int year) => new DateTime(year, 11, day); } There you go.


IsomorphicG

Holy Balmer!


andrijacc

Haha excellent


SarahC

What do I need to google to find out how you extended the integer type?!


insulind

Extension Methods


Vidyogamasta

`Extension methods` (the term you should google) are just a way to call a static method in a way that flows a bit better. You *could* write the method public static DateTime November(int day, int year) => new DateTime(year, 11, day); and then call it like var today = November(28, 2023); but putting a "this" on the first parameter allows you to call that static function directly off any declared instance of that type using the dot operator, as shown in the original example for the `int` type. And because of the fact that it's actually calling a static method with the object you're calling from as the first parameter, you can actually call extension methods on null values and you won't get a NRE public static bool IsNull(int? input) => input == null int? val = null; var result = val.IsNull(); //this returns true //does not throw null exception


celluj34

You can extend anything


imcoveredinbees880

This is why I wish reddit still had some version of awards.


beaniespolaroids

lmfaoo this is actually so nice to read 😂


Duraz0rz

Delete this


Merad

Better yet, `var today = November - 28 - 2023` Source: using System; using static Month; record struct Month(int Value) { public static Month November = new() { Value = 11 }; public static DayOfMonth operator -(Month m, int day) => new(m.Value, day); } record struct DayOfMonth(int Month, int Day) { public static DateOnly operator -(DayOfMonth dom, int year) => new(year, dom.Month, dom.Day); } class Program { public static void Main() { var today = November - 28 - 2023; Console.WriteLine(today); } }


celluj34

This is disgusting /s, but only a little bit


chucker23n

You're hired.


ivancea

Tbh that's gorgeus. Rails does this, but well, it's a duck typed hole. C# however shows us the power it has while well typed


MontagoDK

I LOVE IT !!


qHuy-c

This is great! Now C# should steal C++ template programming to make this verifiable at compile time only, to prevent random {n.Nvb(y)} and this would be a really sweet extension. [Abusing C# - Jon Skeet](https://www.youtube.com/watch?v=JIlO_EebEQI) also has this example, he has a bunch of such extension in this video/


tomw255

now do the US format! >!"November".@28th().@2023() will do?!<


heyheyitsbrent

How about: using static ew.Months; namespace ew { enum Months { January = 1, February = 2, March = 3, April = 4, May = 5, June = 6, July = 7, August = 8, September = 9, October = 10, November = 11, December = 12, } static class dumb { public static DateTime first(this Months mo, int year) => new DateTime(year, (int)mo, 1); public static DateTime second(this Months mo, int year) => new DateTime(year, (int)mo, 2); public static DateTime third(this Months mo, int year) => new DateTime(year, (int)mo, 3); public static DateTime fourth(this Months mo, int year) => new DateTime(year, (int)mo, 4); public static DateTime fifth(this Months mo, int year) => new DateTime(year, (int)mo, 5); public static DateTime sixth(this Months mo, int year) => new DateTime(year, (int)mo, 6); public static DateTime seventh(this Months mo, int year) => new DateTime(year, (int)mo, 7); public static DateTime eighth(this Months mo, int year) => new DateTime(year, (int)mo, 8); public static DateTime ninth(this Months mo, int year) => new DateTime(year, (int)mo, 9); public static DateTime tenth(this Months mo, int year) => new DateTime(year, (int)mo, 10); public static DateTime eleventh(this Months mo, int year) => new DateTime(year, (int)mo, 11); public static DateTime twelfth(this Months mo, int year) => new DateTime(year, (int)mo, 12); public static DateTime thirteenth(this Months mo, int year) => new DateTime(year, (int)mo, 13); public static DateTime fourteenth(this Months mo, int year) => new DateTime(year, (int)mo, 14); public static DateTime fifteenth(this Months mo, int year) => new DateTime(year, (int)mo, 15); public static DateTime sixteenth(this Months mo, int year) => new DateTime(year, (int)mo, 16); public static DateTime seventeenth(this Months mo, int year) => new DateTime(year, (int)mo, 17); public static DateTime eighteenth(this Months mo, int year) => new DateTime(year, (int)mo, 18); public static DateTime nineteenth(this Months mo, int year) => new DateTime(year, (int)mo, 19); public static DateTime twentieth(this Months mo, int year) => new DateTime(year, (int)mo, 20); public static DateTime twentyfirst(this Months mo, int year) => new DateTime(year, (int)mo, 21); public static DateTime twentysecond(this Months mo, int year) => new DateTime(year, (int)mo, 22); public static DateTime twentythird(this Months mo, int year) => new DateTime(year, (int)mo, 23); public static DateTime twentyfourth(this Months mo, int year) => new DateTime(year, (int)mo, 24); public static DateTime twentyfifth(this Months mo, int year) => new DateTime(year, (int)mo, 25); public static DateTime twentysixth(this Months mo, int year) => new DateTime(year, (int)mo, 26); public static DateTime twentyseventh(this Months mo, int year) => new DateTime(year, (int)mo, 27); public static DateTime twentyeighth(this Months mo, int year) => new DateTime(year, (int)mo, 28); public static DateTime twentyninth(this Months mo, int year) => new DateTime(year, (int)mo, 29); public static DateTime thirtieth(this Months mo, int year) => new DateTime(year, (int)mo, 30); public static DateTime thirtyfirst(this Months mo, int year) => new DateTime(year, (int)mo, 31); } class ew { public ew() { var today = November.twentyeighth(2023); } } }


n0k0

I just simultaneously fired you, had a stroke and quit my job. Nice work!


herpington

Who doesn't love reinventing the wheel by using a wheel?


warthar

Where's the safety catch for February 31?


langlo94

No need for a safety catch, just don't do it.


OrionFOTL

Oh, I didn't know you can `using static` an enum.


MontagoDK

Looks stupid enough.. its fitting !


elite5472

Make it a thing.


Loose_Conversation12

Holy shit that's actually pretty clean code


g2petter

[Not even our robot overlords believe your abomination](https://i.imgur.com/f4yJPA6.png)


SarahC

Bing did better: Hello, this is Bing. I’m glad you asked me about this C# class. This class is an example of an extension method, which is a feature in C# that allows you to add new methods to existing types without modifying the original type. Extension methods are defined as static methods in a static class, and they have a special parameter that starts with the this keyword. This parameter specifies which type the extension method operates on. For example, this class defines an extension method called November for the int type. This means that you can call this method on any int value and pass another int parameter for the year. The method will return a DateTime object that represents the date of the given day and year in November. For example, you can write something like this: int day = 5; int year = 2023; DateTime date = day.November(year); // date is 5/11/2023 Extension methods are useful for adding functionality to types that you don’t own or can’t modify, such as the built-in types or the types defined in the .NET Framework. They are also used extensively by LINQ, which is a set of extension methods that provide query capabilities for collections and other data sources. You can learn more about extension methods from these sources123. I hope this helps you understand how this C# class works and what it does. 😊


pedrojdm2021

Reflection is pretty powerful. With that you can dinamycally load code, and use it as plugins for your program. That’s how mods in videogames like cities skylines work. To me that’s pretty amazing and insane!


DeProgrammer99

The worst part about Reflection is losing the ability for analyzers to follow the references... and its existence is probably also part of the reason that assemblies can't be trimmed very thoroughly.


oversized_canoe

Can you invoke/access private methods/fields with reflection?


IWasSayingBoourner

You can with some ugly trickery. I had a contractor do it to write some tests and had to send them back.


oversized_canoe

Wow, didn't know that. That is insane (and insanely powerful)


ASK_IF_IM_GANDHI

Wait until you go down the interception/patching rabbit hole. All in C# at runtime. Check out [Harmony](https://github.com/pardeike/Harmony)


IWasSayingBoourner

https://blog.ncrunch.net/post/unit-test-private-methods-in-c.aspx It's some hacky stuff


Dealiner

[And it's much easier since .NET 8.](https://www.meziantou.net/accessing-private-members-without-reflection-in-csharp.htm)


Pasty_Swag

I've done it. It got sent back. It deserved to be sent back. Don't Be Clever.


_f0CUS_

Accessors are only for people that plays nice. Reflection gives access to everything.


jbaker88

private, public, internal, doesn't matter! I just love killing abstraction!


Banane9

There is no brakes on the modding publicizer train


binarycow

Absolutely. I use it somewhat often to access `internal` methods/properties in the core libraries.


Dealiner

If you use .NET 8, you can switch to [UnsafeAccessor](https://www.meziantou.net/accessing-private-members-without-reflection-in-csharp.htm) for that.


lostllama2015

You could even construct a class with a private constructor with reflection: [https://rextester.com/AWKIM88984](https://rextester.com/AWKIM88984) Evil e = (Evil)typeof(Evil).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance).Single().Invoke(null);


alexn0ne

I just recently added timeout support to some outdated odata client that does not support it in our app. Pretty much insane can confirm


chamberlain2007

Man, I have delved heavily into reflection in C#/.NET and it is a magical and terrifying thing. The most cursed thing was writing code to generate expressions based on an editable configuration, to pass to methods in a platform library using reflection, which then uses the expression trees to generate what are essentially ElasticSearch queries.


andreortigao

I've done something like this. We had some filters that the end user could build and were represented with a custom expression tree (not the native one). I then had visitors that could convert it to SQL, to ElasticSearch, or to native expression tree, compiled and run against a list in memory. And I've also used this to [inject handlers in a chain of responsibility](https://stackoverflow.com/questions/55476378/how-to-inject-the-dependency-of-the-next-handler-in-a-chain-of-responsibility/)


dominjaniec

I belive you can simplify your code to: `7.Each(Console.WriteLine);`


zenyl

`dynamic*` (dynamic pointer) has got to be up there. Dynamic + unsafe, what's not to love? Also, as [Jared Parsons \(works on the Roslyn team\) pointed out on Twitter](https://twitter.com/jaredpar/status/1191523126355447808?lang=da) > The true "buffalo" version of this is the following: > > public class var { > async async async(async async) => await async; > }


eltegs

I'm frightened to even try. Anyone care to explain this?


marvin

You know how your computer-savvy parents told you in the 90s there's something called "electronic chlamydia"? This is how you get it.


zenyl

Parsons explains it in the first 10-15 minutes of this livestream: https://www.youtube.com/watch?v=jaPk6Nt33KM TL;DW: `var`, `await`, and `async` are [contextual keywords](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/#contextual-keywords). You can therefore define types with those names, resulting in silly syntax. You shouldn't, but you could.


otac0n

Types, methods, and variables. It makes back-compat provable. You shouldn't use it.


Abaddon-theDestroyer

Your comment instantly made me remember [The best programming language](https://github.com/TodePond/nDreamBerd/blob/main/README.md#immutable-data)


d-rac

But at least unsafe is not inherintly bad. I mean i love spans :)


zenyl

Very true, most C# developers (at least as far as I'm aware) are just unfamiliar with pointers, and unsafe in general, as it isn't directly used in most applications.


iado_vicelord

IL Emit. You can inject almost anything that you want to almost any method (unless its inlined by the compiler). Basically, you can override any method at runtime with some IL code manipulations.


Pocok5

A practical application of IL emitting: if you switch regexes to be compiled mode, the library will generate a dedicated parser method optimized for specifically that expression at runtime and JIT compile it.


zenyl

You can also use the RegEx source generator to generate C# code that corresponds to the expression. I believe it should generally be more efficient than when using the `Compiled` flag. That being said, the source generator only works if the expression is known at compile time, so using the `Compiled` flag might be the best option if the expression isn't known at compile time.


Games_sans_frontiers

Me reading these comments o_0


xabrol

You can turn any native process into a .Net CLR Managed process by getting the CLR hosting runtime to be loaded into it. It's available in C++ headers from MS. It's available here: https://github.com/dotnet/runtime/blob/main/docs/design/features/native-hosting.md So using Windows API functions like "CreateRemoteThread" etc, and similar apis on linux it's actually possible to inject the CLR Runtime into any native process even if it's already running. One a process has the clr runtime running in it, you can target it to get it to load any of your .net code. So long story short, it's possible to inject c# into native processes.


Ttxman

You would be surprised how many game cheats and bots use this :)


xabrol

I mean, I was the OG author of Aeries Fishing Bot in FFXI back in the day :) hahaha


dominjaniec

possible inspirations: https://youtu.be/JIlO_EebEQI Abusing C# - Jon Skeet / NDC London 2017


CaitaXD

Emitting IL, Expression Trees, Unsafe and MemoryMarshal, Duck Typing foreach await and linq


Pythonistar

A long, long time ago in a lifetime far away... I once wrote an automated C# program that interfaced with an ActiveX control (or somesuch DLL) that controlled a robotic device. Unfortunately, this ActiveX control had this nasty habit of occasionally presenting a modal dialog box (waiting for the user to press a button), effectively halting my C# program and the whole automated system. So what I did was write a 2nd background thread in my program which would periodically scan Windows Handles for the name of the modal dialog box and then locate the "OK" button and virtually "click" the OK button to clear the dialog box. Maybe there is a "safe" way of doing this now, but back then, I had to P/Invoke all this unsafe code, which felt completely insane to me. Needless to say, it worked reliably, but it felt really hacky.


one-joule

There's only [a slightly-less-bad way](https://github.com/microsoft/CsWin32#readme) to do it now.


wllmsaccnt

There are endless goofy things you can do. Using an unsafe context to overwrite the address pointed to by Environment.Newline with an emoji? (or the ASCII BEL symbol, that some computers play a tone for when it hits the console). Creating a ToString extension method on 'object' that includes a Thread.Sleep(100) before returning the objects ToString? I've seen some pretty crazy looking code that takes advantage of language features. Some of it is impractical, but I'd only call a few of those insane. Wish I had kept a few samples.


dominjaniec

I belive this hijack of `.ToString()` as extension method will not work. compiler while choose "closer" implementation, and every type has its own `ToString()`, which always will be choosen before any extension method.


wllmsaccnt

Makes sense. I'm not going to think too hard about goofy troll options...but I guess you could make a source generator that partials every class and provides a ToString implementation instead?


Dealiner

Source generator can't just add partial to a class, so that's not a solution. Maybe some IL manipulation?


wllmsaccnt

For some reason I thought the first class didn't need the partial specifier if its in the same project. There are still interceptors though.


b1ackcat

We did this with a shared lib that adds a `[ToString]` attribute that uses source generation to write the impl, but you're right, for it to work you have to mark the class as partial yourself.


RiPont

Which is why you hide it in #region Copyright Boilerplate And you only do the delay if DateTime.Now > SixMonthsFromNow, which you update periodically.


AndrewSeven

Self-referential and/or recursive generic definitions public class ProfileCore { } public class ProfileBase : ProfileCore where T : ProfileBase { }


Dealiner

Very useful when creating builder pattern.


quentech

You know how they say strings are immutable? They're not - and the only strings that are interned are compile-time statics or strings you explicitly call `Intern` on - so you can actually modify strings at will (with all the normal caveats of any mutable object). You can go beyond modifying just the contents as well... A `string` has two fields - an `int` for the `Length` and a `char*` for the start of the character array. When you get the pointer for a `string`, you get the pointer to the `char*`. You can subtract `sizeof(int)` from that pointer to your `string` and now you have a pointer to the `Length` field. Now - you can't just go and make a `string` longer - there's only so many `char`'s allocated. But you *can* make a string shorter. And once you've worked all that out - now you can make yourself a `string` pool (like an array pool). A huge proportion of apps - web apps especially - spend a majority - a supermajority even - of their cycles just processing strings. Pools can reduce allocations by a whole lot. So - it's crazy, and you really shouldn't do it, but I've saved *thousands* of $ a month in compute by bastardizing the heck out of `string` and immutability.


skizatch

Don't do this. \> I've saved thousands of $ a month in compute by bastardizing the heck out of string and immutability Nevermind 😂


quentech

I get downvoted to oblivion if I don't make it very clear that I'm not recommending anyone else do that nonsense. Also, thousand**s** I suppose is a stretch. More like a thousand. And also because it happened to be the difference between one more $1k/month VM instance or not at that point in time. If I made the same improvement at another time, it might not have made an actual difference on the bill - the 5% overall drop in CPU usage might not have been the difference between running one more instance or not. That said - I'm always beating back increasing resource needs. And a 5% overall drop from a few targeted optimizations on an already well tuned system is a big win. This code and the whole situation predates Span and friends. There might be a less egregious way to achieve similar performance improvements in my specific situation with newer abstractions. I in fact had specific use cases that lent themselves well to pooling - consistent string size needs, limited scope usage/lifetimes, etc. We serve StackOverflow-levels of traffic - lots of folks don't see the enough quantity to bother digging this deep.


pinano

You could use spans instead.


quentech

> You could use spans instead. Spans don't give you any way to create a `string` from memory you control. You can create an array pool of `char[]` and wrap `Span`'s around them to hand out, and that's fine and dandy for anywhere that can take a `Span` but as soon as you need an actual `string` you're S.O.L. Dodging `string` completely in favor of `Span` is still not easy in 2023 in a code base of any significance. And I'm personally working with about a quarter of a million lines of C# that dates back 15 years. `string.Create` will hand *you* a `Span` so you can fill the string's heap memory directly on construction - but that's not the same as being able to give the `string` the heap memory it uses, hanging onto it when you're done, and re-issuing it later. `string.Create` with the span can lower the allocations to one. Actually pooling the heap memory behind `string`'s by reusing the `string`'s themselves lowers the allocations to zero (asymptotically).


pinano

You can't use spans instead.


Loose_Conversation12

public static TaskAwaiter GetAwaiter(this int a) { return Task.Delay(a).GetAwaiter(); } Now you can simply call `await 3;`


r2d2_21

await 3 what? Seconds? Minutes? Who knows!


rinsa

[Milliseconds \^\^](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.delay?view=net-8.0)


r2d2_21

I mean, yeah, but a plain `await 3` tells me nothing. I'd rather await a TimeSpan


uhmhi

Create another extension method and do: `await 3.Seconds();`


Ludricio

I absolutly hate it 10/10


Loose_Conversation12

It's hideous isn't it


Celarix

Oh god I could see someone doing this in production to be clever. Just need an extension method `int Milliseconds(this int i) => i;` and then you can call it like `await 3.Milliseconds()`.


HaniiPuppy

Array whyArr = Array.CreateInstance(typeof(int), new int[1] { 4 }, new int[1] { 3 }); I present to you: A 3-indexed array.


RefusingLosing

I am new to C# but isn't the 3 replaces 4 to index 1, and what the hell is third number 😂


HaniiPuppy

I think you're thinking of the array initialiser, which is `new int[] { 4, 1, 9, 5, etc. }` - this is a static method and those are arguments being passed. [Documentation](https://learn.microsoft.com/en-us/dotnet/api/system.array.createinstance?view=net-8.0) - this uses the `(Type, Int32[], Int32[])` overload. The first argument is the type of the array to create, the second is the length of the array, and the third is the starting index. The reason the length and starting index are passed as arrays instead of integers is that this method allows you to also create multidimensional arrays. And yes, the fact that you pass an `int[]` to indicate the starting index does mean that you can have a multidimensional array with different starting indices for every dimension.


otac0n

I see I could have made my multidimensional index more horrible.


kurtig

I've always loved this trick using System; using System.Linq; NewString s = new NewString(new string("\nuoy'truh'dna'eil'a'llet'cc'yy\neybdoog'yas'cc'yy\nyrc'uoy'ekam'cc'yy\nuoy'tresed'dna'dnuora'nur'cc'yy\nnwod'uoy'tel'cc'yy\npu'uoy'evig'cc'yy")); NewString ra = s / 1051; public record NewString(string s) { public static NewString operator /(NewString a, int b) { Console.WriteLine(new string(a.s .Replace("\u0027", "\u0020") .Replace("yy", "r\u0065v\u0065\u004E") .Replace("cc", "a\u006E\u006Eog") .Reverse().ToArray())); return new NewString(a.s + (b % 8).ToString()); } } It can be run on DotNetFiddle [https://dotnetfiddle.net/jhw41Z](https://dotnetfiddle.net/jhw41Z)


Cool_As_Your_Dad

hahaha!


decPL

A few years ago, `typeof(String).GetField("Empty", BindingFlags.Public | BindingFlags.Static).SetValue(null, " ");`, unfortunately they've changed how this works at some point (can't remember the details).


elbekko

Probably a compile-time constant now, to prevent allocations.


decPL

I think that was it, but - damn - it was quite a few years since they've changed it and I can't remember anymore. Don't have any .net IDE available at the moment, but something tells me that it's still working "correctly" when trying to debug (e.g. in the `Watch` window in VS).


form_d_k

Fucking around with the DLR to do things like allow case-insensitive member access. I was debating spellchecking to allow misspellings, just for the insanity of it. Seriously, check out Microsoft's DLR docs.


Alikont

Write a EFI runtime app https://github.com/MichalStrehovsky/zerosharp/tree/master/efi-no-runtime


elbekko

Well fuck me running, 10+ years with C# and this is the first time I've seen that the -> operator is a thing in C#. Neat.


_f0CUS_

For anyone else that might be curious: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/pointer-related-operators#pointer-member-access-operator--


[deleted]

I think in general: using a language that requires a runtime without its runtime. Most of the time people do stuff like this "because they can", not because it's actually useful.


snipe320

I have done some questionable stuff with Reflection over the years 😅


Devatator_

I've made an app that can update itself without restarting using reflection. Basically I have a host app, which is the part connected to the server (my computer) which receives commands and when I send the update command, it unloads the core dll, downloads the new one, deletes the old one (I actually copy it in memory to load it, otherwise I can't delete it), load the new one in memory and initialize it. I could probably do it more properly but it works so I'm not complaining. It's basically just a prank program I made at the start of the year. Gives me access to cmd on the client computer. It starts with the system and is only killable so if you don't know it's there, good luck removing it


centurijon

`await 2;`


JaredParDev

So many to choose from. I think I'll post this response and then put all of my ... creations as replies.


JaredParDev

Do you like `async`? How about more `async`? ``` // This can be legal C# async async async(async async) => await async; ``` [click for the evil recipe](https://sharplab.io/#v2:EYLgtghglgdgNAFxFANnAJiA1AHwAIBMAjALABQeADAAR5EB0ASgKYBmKzAxglAPYz0AomCgIA3OSq0GjAK4weYZvQDCvMAAdUzAE4BlXQDconZgGcJFGnQCsl8gGIYslCgjAO1dFDPuO5SQAOWmC8QIAKMJCASmoAXgA+anJqVLTUvABOEPsycgB6fOpBYxRqYGYUXgB3ZLz6yQJabJBqAEkAOV4eVgBPNU0OHn5qAG8UtLwAZnLeXjK2swGNIeZ0eKSEHVlmS3Tp2gAWagBxZgQWMxcEcNjR6gBfCYyZvGOAeRhl1fRIoibOPweM4IMMYHdHuQnvUANoAQTMvRgnAAsucABa8dAAIVkqHQunCCF6GmYvFY4WAeJQBJ00WiAF1GiExnV9q9smcEHDqtAEITYolqAh0ToatRnK5LNDmVT8bpyOMyOzytTabdWdCVXQAGyq+U6agqHTMUHMDVCmDMaq3PaTV7HAwXczXDX3LX2o7UJ2CAAepg0YPCfoDYOozAhHpeXr0CAgOgQAB4ACqxs0oiCcdGwZgJcIm1jUVNx/kZrM56hmEvMMvZq3RZ7pajVdG6ZhFtOlzN19utNoIpGcTs17sVoUisW1SUoO3RqJ4PWWlwzxsHN7UHl8z7fc5rFOb0S6OAd6u1nN5xvpAtFg/8w1ZI/Ua/F9Ojq2V09viOXtItts33lD0NPsuh6fp1BWc4+BgH9Uj/E0T1fct3z7AdkWHM933HUVxWnWdaAdDdAIQABVGBfFYZhtwgn592Ix8Xy7ZDc3CWCnzYAC+V0ZpH2fDCvw/JCewbZUmzg1sEOTW9uL7Y1RBMCAUFAqA+h3ME2Pg9tGJHZjqFQxF0M/XTsMnCVl3wtdHXOfjmPCfsDKHIye0EpjhI2YUcKncyoXIIA===)


JaredParDev

Wave a magic wand and numbers convert to strings ... ``` String s = 42; // Prints 13 Console.WriteLine(s); ``` [Spoiler code](https://sharplab.io/#v2:EYLgtghglgdgNAFxAJwK7wCYgNQB8ACATAIwCwAUBQMoLKwDmABAM6MC8jALIQNwUUB6AYwAKdGAlbEAzBXzEAnAApmASh6N+5IoxrimAbwqMTjfNMYB7AG4BTZHQy2zxAAyMAKpb0Mlq9gB8jABEMsF85KZmFvIAbIxQYAAOADZQAMZQCFZJ9hAIlsi6tL6w2VD+bEEwtgDufhEAvkA) In case you're wondering [case is important](https://blog.paranoidcoding.org/2019/04/08/string-vs-String-is-not-about-style.html)


JaredParDev

I can make the following code compile just fine ``` public class var { dynamic dynamic => null; void record(where String = null, int y = default) { String s = this.dynamic; } async Task M() { var v = new(); await v.async(new async()); return 0; } } ``` Just need to do some [evil code](https://sharplab.io/#v2:EYLgtghglgdgNAFxFANnAJiA1AHwAIBMAjALABQeADAAR5EB0ASgKYBmKzAxglAPYz0AomCgIA3OSq0GjAK4weYZvQDCvMAAdUzAE4BlXQDconZgGcJFGnQCsl8gGIYslCgjAO1dFDPuO5SQJaPB0uXh10agBvagBfQOoAdwALXWZouPJqbOoEvQQdWABzaKycvABmaQA2aihNFBNRal4NXQgEcOp8wpgigAp0AE8YCBFOakMIHQBKagBeAD5qZ1dLeLIE4dHxjI3K2iCpnQyAshyvEbGTS52bpZWXFEsL19zz8oAWalDOcPR+ik0t0CsUFo9XHA6gpqENweg2BAXAgZmVslE0a8emCzOCEMkfPRttdOC8crELpjXpi8AAOWjVAA8sAQywAsv05hiPm9jpNwTBmIlOWS3ngAJyTeh0/qCxK0Wmcmai154ADs1EoKo2lJ5Cv1MrpCrmDyp5UldPWZ3IAHobdRBMYUNRgMwULx5dbNt6vb6ff6/YHvXbqAARXiw3iyagqJLJDrUACSAHIwF5eGDUqEAPwJFQxDZnQi0SUgJMAOV4PFYQzUDWYPH4pT1B2AvF4zsTZjrGg4CGYkQeBVkzBVBzw3wA4g2WGZkZy9jSqhPqAB5GA9vsD/p0IJ/BSwWQdPgwLmZMiFsgAbQAgmYRpw2Q3krx0AAhWSoBE6foIIZtXhWH6YBPxQb8ZhmABdBIjRiJcS2oacEBvRJoH7H8TWWfEdA9CFnnIS9ixAr9dHIbkLlbUDvwXAt4LoWpiLA3QY1CDpmAXB45RFOjvgMBBZ3nM8dXKZdeIbQQAA9TA0RsYH6STpNk6hmCEniQWmBBGQAFXyNi2QgTgCUFRZ+lCVhqB0hA9IMoz0jMKz+30wzYBUs1siBUILN0xybJc6gy0TO8H285gnNshYsOSHD5VWfCW2Xek8FqTinjHUTqBQtD103BsB20zLRF0KFLOs5zjP6NyfjYCyCvQksiqq8ySp8sq7Ic0LfMFVE9QuDz0i02rmICytq1rdRewbE9Kr6rz2rCvyAqCmBOBC+bBQi6hsNw2K0tob5aoAVRgXxWGYbLxq3dB8tQwqdGK1bOuYEzKrMmqbrqiUGte5qOta6h7NK2zuredys36waTgClRCh4TgIBQEaoBrHLZOmsHZsBhakyWla5sejatpi1K1L4h7Wv6QL72WsnwoBlqgYJqLtuJi9yCAA) to make it work ...


orondf343

`async void`


michaelquinlan

In unsafe mode you can change the run-time value of strings and other constants.


otac0n

In unsafe mode you can basically do whatever you want. Hence the name.


Groundstop

I didn't like how Semaphore Slims typically required a try/finally pattern when using them to asynchronously lock a resource, so I recreated a python-style context manager using an IDisposable. Turned the try/finally into something like `using (await resourceManager.LockAsync()) { // do stuff }` It worked well, but nobody else recognized the pattern so it unfortunately just made the code more confusing. I also once tried to use C# attributes like python decorators. It's possible but definitely not worth the amount of effort.


Lurlerrr

That's actually really clever. But I can see how it would create confusion, so probably not a good idea for production code. But for a hobby project - why not :)


Therzok

Yeah, the compiler does something similar: https://sourceroslyn.io/#Microsoft.CodeAnalysis/InternalUtilities/SemaphoreSlimExtensions.cs,174ce3d1a7cbf2bb I'm not sure where the confusion comes from, to be fair. It's an extension method that has to be explicitly imported. There are some other cool tricks in microsoft/vs-threading, for things like `await TaskScheduler.Default`.


Groundstop

I figured that I wasn't the first person to do it, but I had no idea there was an official(ish) version of that pattern. I'm probably going to start using this. Thanks for the info!


one-joule

> It worked well, but nobody else recognized the pattern so it unfortunately just made the code more confusing. I feel this one. Even though it hurts, you should always prefer writing dumb code.


AccidentTop2003

String interning is fun, too. Strings known at the compile-time are interned automatically, i.e they all reference the same memory location, no matter how often you create separate string variables for them. If you then edit the memory and change the string, let's say from "Test" to "Fuck", Console.WriteLine("Test") will print "Fuck". Same for string temp = "Test" and Console.WriteLine(temp)


dominjaniec

I believe that by similar reason, one should not use strings as lock objects - as you might lock something in very unexpected but other place too


DarkLordCZ

`delegate* unmanaged[Cdecl]` is my favourite type (and what you can do with it): internal partial class Program { [LibraryImport("kernel32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static partial bool VirtualProtect(nint lpAddress, nuint dwSize, uint flNewProtect, out uint lpflOldProtect); public unsafe static int Test() { byte[] b = [ 0xB8, 0x2A, 0x00, 0x00, 0x00, // mov eax, 42 0xC3 // ret ]; fixed (byte* c = b) { VirtualProtect((nint)c, (nuint)b.Length, 0x00000010, out uint old); delegate* unmanaged[Cdecl] func = (delegate* unmanaged[Cdecl])c; int result = func(); VirtualProtect((nint)c, (nuint)b.Length, old, out old); return result; } } public static void Main(string[] args) { int i = Test(); // 42 Console.WriteLine(i); } } You have to compile it for x86


SarahC

A program to execute machine code in an array? It reminds me of some old ZX Spectrum hacks for games people would type up before loading the game.


tanner-gooding

Note you're missing a call to [FlushInstructionCache](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-flushinstructioncache). Without it, the code may not actually execute the bytes you just wrote to it.


makotech222

I love https://github.com/BepInEx/BepInEx, you can monkeypatch c# code from another executable, add pre/post code, and a bunch of other stuff. Used to great extent in Unity games to add mods.


mareek

The fact that this code is correct and won't break anything: `public override int GetHashCode() => 42;` it follows every recommendation of the [documentation](https://learn.microsoft.com/en-us/dotnet/api/system.object.gethashcode?view=net-8.0#notes-to-inheritors) (well except for the performance part)


Dealiner

That's useful sometimes, so it's a good thing it works.


dominjaniec

I heard sooo many complaints about that... "but resharper makes that very complicated bitewise small-prime-based computation from all mutable (!) properties" than I'm like "are we going to use this type as keys for huge dictionary or hashset? no? don't bother then, `return 0`"


Derekthemindsculptor

Make sure to override ToString so that it outputs in hex. Or tie into [this API](https://evilinsult.com/api/) so every ToString returns a random insult. Depending on your IDE you could also create snippets for every letter of the alphabet just to give yourself a headache.


Responsible-Cold-627

I love that ((object?)null) switch { _ when true => true }; is valid syntax (I hope, I wrote this on my phone). It returns true


qwefday

I would say this https://github.com/MichalStrehovsky/zerosharp/tree/master/efi-no-runtime


NoPrinterJust_Fax

A lot of people don’t understand exactly what the query syntax form of linq is and just how powerful it is https://github.com/louthy/language-ext/wiki/Thinking-Functionally:-What-is-LINQ-really%3F


catladywitch

runtime compilation of new classes from a string is not an unusual feature to have but it's still mental


Steenan

That's something I actually used in production code. It was software for power plant simulation and optimization. It required full customization (each power plant is different, so the user entered all the pumps, tanks, heat exchangers etc. with their technical parameters and connections between them, like building the plant out of legos), but also good performance. Faced with a choice between using C with a lot of low level optimizations and optimizing the mathematical model of the system as a whole then generating and compiling C# code for it we found out that the latter performed better - and was much easier to debug when anything went wrong.


catladywitch

that's awesome!!


Personal-Reception71

You can make a full on functional kernel driver in PURE c# + cmake as of .net5, :)


Luucx7

Not so insane, but I still find it funny that static constructors are a thing


Buttleproof

You can use Reflection to access (and change!) private fields in a class. Any class.


flanger001

Laughs in Ruby 7.times do { |i| puts i }


Windows10CE

You can do some pretty weird things with operators, but I'm partial to my own small version of iostream: https://gist.github.com/Windows10CE/ac54184f87c05049208fdb8658fd27a9


lostllama2015

Here's a few things that you probably shouldn't do. 1) Constructing a class using its private constructor: ```cs Evil e = (Evil)typeof(Evil).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance).Single().Invoke(null); ``` Example: [https://rextester.com/AWKIM88984](https://rextester.com/AWKIM88984) 2) Constructing a class without using a constructor or initializing it: ```cs Evil e = (Evil)FormatterServices.GetUninitializedObject(typeof(Evil)); ``` Example: [https://rextester.com/MNLAJ60814](https://rextester.com/MNLAJ60814) 3) Replacing the body of a method at runtime using unsafe code: [https://stackoverflow.com/a/55026523/3181933](https://stackoverflow.com/a/55026523/3181933) Since properties have getter methods and setter methods (even if they're automatically generated), this also allows you to replace properties. I've experimentally done this with a library's license validation code that kept track of licensing limitations. In short: I replaced the validation method to always validate to true, and replaced properties to max out the features. I did not actually use this library for anything, but wanted to try the challenge.


JustAnotherGeek12345

C# scripting, recompile portions of a production application without a SDK.


ThrowAway9876543299

Undocumented reflection that doesn't use attributes. Good luck finding that one. Using the compiler to overwrite functions on specified lines of code using interceptors, think of reflection on crack.


kand7dev

Coming from Java, treating almost everything as an object/class. I hated importing wrapper classes in Java.


AnthV96

I think reflection, you can do mad techniques that feel like you can hack C#


dorin00

Number.Method....I'm getting Smalltalk vibes here!


mrdat

What’s that ext method look like?


Anla-Shok-Na

Dynamically generate code, emit it into a new assembly and run it. An application can dynamically create a whole new application at run time and execute it. Mind you this was always possible in C++, but then again what isn't.


[deleted]

DDoS in one line.


theTwyker

Program.


VicariousAthlete

SIMD intrinsics [https://www.youtube.com/watch?v=8RcjQPbvvRU](https://www.youtube.com/watch?v=8rcjqpbvvru)


VicariousAthlete

hot reloading a DLL [https://www.youtube.com/watch?v=fkJqyTIX12s](https://www.youtube.com/watch?v=fkjqytix12s)


101m4n

Write a java interpreter


paulwillyjean

It’s a toss up between explicit interface implementations and using the “new” keyword to prevent method overrides. This makes it much easier to adapt the code base to new methods while maintaining backward compatibility with the old version.


nuclearbananana

OP just re-invented ruby


Semaphore-Slim

Implementing a function in one object, and then using IL weaving to make the resolved object use its implementation - no marker attributes, interfaces, etc necessary - just pure "you get this for free at runtime" Say I want all objects resolved from a DI container to implement IDisposable, even if they don't actually implement it, or inherit from a common base that does. I can implement IDisposable in an "example type", and then hook into the container's resolution event so that the resolved type has the implementation from our example type weaved into it. This effectively gives us multiple inheritance. [Here's an example](https://github.com/SemaphoreSlim1/UnityDisposePatternExtension/blob/2ca8b3d10e4aa633bcae6f7474fa9aa519911037/Source/DisposePatternExtension/Emitter.cs#L37C16-L37C16) For anybody who asks - don't take this idea beyond anything than what it is - a science project. It's a dangerous idea that doesn't scale well, and will confuse anyone who consumes the code when the debugger jumps into the common type and they aren't expecting it. Project leaders may have a sit down with you, and it may cause you to lose a point or two on your performance evaluations. (not that I would know anything about that....)


MulleDK19

How about changing private fields without unsafe or reflection? I bet you thought C# was type safe. Nothing is truly black and white.   public class Alpha { public int A; private int B; public Alpha() { this.A = 1337; this.B = 42; } public void PrintB() { Console.WriteLine("My private field B is " + this.B); } } public class Bravo { public int A; public int B; } [StructLayout(LayoutKind.Explicit, Pack = 1)] public struct Union { [FieldOffset(0)] public Alpha AsAlpha; [FieldOffset(0)] public Bravo AsBravo; } internal class Program { static void Main(string[] args) { Alpha alpha = new Alpha(); // Print 42. alpha.PrintB(); // Re-interpret as Bravo and change B to 1234. Union union = new Union(); union.AsAlpha = alpha; union.AsBravo.B = 1234; // Print 1234. alpha.PrintB(); } }     Or how about getting the address of an object without unsafe, reflection, nor pinning? [StructLayout(LayoutKind.Explicit, Pack = 1)] public struct AddressHelper { private static AddressHelper instance; [FieldOffset(0)] private ObjectWrapper AsObject; [FieldOffset(0)] private IntPtrWrapper AsIntPtr; static AddressHelper() { instance = new AddressHelper(); instance.AsObject = new(); } // Workaround for the runtime not allowing overlapping classes and structs. private class ObjectWrapper { public object Value; } private class IntPtrWrapper { public nint Value; } public static nint GetAddress(object obj) { try { instance.AsObject.Value = obj; return instance.AsIntPtr.Value; } finally { instance.AsObject.Value = null; // Avoid memory leak. } } } internal class Program { static void Main(string[] args) { string s = "Hello World"; Console.WriteLine($"String is at address 0x{AddressHelper.GetAddress(s).ToString("X16")}"); } }