SharpLab | .NET language playground | Compiler library
kandi X-RAY | SharpLab Summary
kandi X-RAY | SharpLab Summary
This repository contains source code for SharpLab is a .NET code playground that shows intermediate steps and results of code compilation. Some language features are thin wrappers on top of other features -- e.g. using() becomes try/finally. SharpLab allows you to see the code as compiler sees it, and get a better understanding of .NET languages. Recent versions include experimental support for running code, with some limitations.
Support
Quality
Security
License
Reuse
Top functions reviewed by kandi - BETA
Currently covering the most popular Java, JavaScript and Python libraries. See a Sample of SharpLab
SharpLab Key Features
SharpLab Examples and Code Snippets
Community Discussions
Trending Discussions on SharpLab
QUESTION
I have a future that has a generic parameter, which is a superclass (A
) of another class (B extends A
). I know for a fact that the instance of the value of the Future is of the subtype. Why can't I downcast the Future
to Future
in dart? If I unwrap the Future once and then wrap it again using async/await, it works.
Here's an example:
...ANSWER
Answered 2022-Mar-17 at 19:21QUESTION
I am having an issue using TypeBuilder to dynamically create a derived type that has a static field of the base type, that is initialized to a new instance of the created type.
Essentially, I want to create this dynamically:
...ANSWER
Answered 2022-Feb-18 at 17:34Thanks to Kirk Woll's tip, I was able to spot my error.
OpCodes.Stsfld
not OpCodes.Stfld
.
(facepalm)
QUESTION
Given a parent record type:
...ANSWER
Answered 2021-Dec-28 at 16:06This is the stack trace when calling new Bar("foo") == new Foo("foo")
:
QUESTION
I'm calling a C# API which uses overloads and optional parameters.
Unfortunately, one of the overloads is a params object[]
and F# selects it over a more specific overload which I intend to call. How do I make F# select the overload I want?
ANSWER
Answered 2021-Dec-07 at 00:45To call the expression version with two arguments, you need:
QUESTION
I'm trying to use Reflection.Emit to generate the code for Call
method of following code:
ANSWER
Answered 2021-Nov-11 at 17:11As mentioned in issue https://github.com/dotnet/runtime/issues/11354, it is not currently possible to use function pointers in reflection stack (typeof(delegate* ...)
always returns IntPtr
currently), so there is no way to make Reflection.Emit work reliably in this case.
QUESTION
Why does the Roslyn compiler generate local functions with the internal
access modifier (in IL, assembly
) instead of private
?
ANSWER
Answered 2021-Oct-20 at 14:42Looks like code reuse artifact. Roslyn probably uses same code to handle local functions and lambdas, but injects method definitions in different classes.
In case of lambda it injects lambda body to generated closure (DisplayClass
) class and it should be internal to be referenced from calling function.
QUESTION
I noticed by chance that the following code compiles (VS2022preview , c#10):
...ANSWER
Answered 2021-Oct-09 at 08:43https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/records
Pretty much what documentation says. C# 9.0 introduced many such changes. Top level program file, top level namespace declaration etc where they got rid of mandatory curly braces.
QUESTION
How can I downcast a trait to a struct like in this C# example?
I have a base trait and several derived structs that must be pushed into a single vector of base traits.
I have to check if the each item of the vector is castable to a specific derived struct and, if yes, use it as a struct of that type.
This is my Rust code, I don't know how to implement the commented part.
...ANSWER
Answered 2021-Sep-09 at 02:52Technically you can use as_any
, as explained in this answer:
How to get a reference to a concrete type from a trait object?
However, type-checking and downcasting when looping over a vector of trait objects is considered a code smell. If you put a bunch of objects into a vector and then loop over that vector, presumably the objects in that vector are supposed to play a similar role.
So then you should refactor your code such that you can call the same method on your object regardless of the underlying concrete type.
From your code, it seems you're purely checking the type (and downcasting) so that you can call the appropriate method. What you really should do, then, is introduce yet another trait that provides a unified interface that you then can call from your loop, so that the loop doesn't need to know the concrete type at all.
EDIT: Allow me to add a concrete example that highlights this, but I'm going to use Python to show this, because in Python it's very easy to do what you are asking to do, so we can then focus on why it's not the best design choice:
QUESTION
Is there any reason for the C# compiler to emit a conv.r8 when casting from double -> double
?
This looks to be completely unnecessary (casting from int -> int, char -> char, etc) does not emit equivalent conversion instructions (as you can see in generated IL for the I2I()
method).
ANSWER
Answered 2021-Sep-05 at 03:19The short version is that the intermediate representation of double
/float
in the CLI is intentionally unspecified. As such the compiler will always emit an explicit cast from double
to double
(or float
to float
) in case it would change the meaning of an expression.
It doesn't change the meaning in this case, but the compiler doesn't know that. (The JIT does though and will optimize it away.)
If you want all the gnitty gritty background details...
The ECMA-335 references below specifically come from the version with Microsoft-Specific implementation notes, which can be downloaded from here. (Note that since we're talking about IL I will be speaking from the perspective of the .NET Runtime's virtual machine, not from any particular processor architecture.)
The justification for why Roslyn emits this seemingly unnecessary instruction can be found in CodeGenerator.EmitIdentityConversion
:
An explicit identity conversion from
double
todouble
orfloat
tofloat
on non-constants must stay as a conversion. An implicit identity conversion can be optimized away. Why? Because(double)d1 + d2
has different semantics thand1 + d2
. The former rounds off to 64 bit precision; the latter is permitted to use higher precision math ifd1
is enregistered.
(Emphasis and formatting mine.)
The important thing to note here is the "permitted to use higher precision math". To understand why this is we need to understand how the runtime represents different types at a low level. The virtual machine used by the .NET Runtime is stack-based, all intermediate values go onto what is called the evaluation stack. (Not to be confused with the processor's call stack, which may or may not be used for things on the evaluation stack at runtime.)
Partition I §12.3.2.1 The Evaluation Stack (pg 88) describes the evaluation stack, and lists what can be represented on the stack:
While the CLI, in general, supports the full set of types described in §12.1, the CLI treats the evaluation stack in a special way. While some JIT compilers might track the types on the stack in more detail, the CLI only requires that values be one of:
int64
, an 8-byte signed integerint32
, a 4-byte signed integernative int
, a signed integer of either 4 or 8 bytes, whichever is more convenient for the target architectureF
, a floating point value (float32
,float64
, or other representation supported by the underlying hardware)&
, a managed pointerO
, an object reference- *, a “transient pointer,” which can be used only within the body of a single method, that points to a value known to be in unmanaged memory (see the CIL Instruction Set specification for more details. * types are generated internally within the CLI; they are not created by the user).
- A user-defined value type
Of note is the only floating point type being the F
type, which you'll notice is intentionally vague and does not represent a specific precision. (This is done to provide flexibility for runtime implementations since they have to run on many different processors, which may or may not prefer a specific level of precision for floating point operations.)
If we dig around a little further, this is also mentioned in Partition I §12.1.3 Handling of floating-point data types (pg 79):
Storage locations for floating-point numbers (statics, array elements, and fields of classes) are of fixed size. The supported storage sizes are
float32
andfloat64
. Everywhere else (on the evaluation stack, as arguments, as return types, and as local variables) floating-point numbers are represented using an internal floating-point type.
For the final piece of the puzzle, we need to understand the exact definition of conv.r8
, which is defined in Partiion III §3.27 conv.
- data conversion (pg 68):
conv.r8
: Convert tofloat64
, pushingF
on stack.
and finally, the specifics of converting F
to F
are defined in Partition III §1.5 Table 8: Conversion Operations (pg 20): (Paraphrased)
If input (from the evaluation stack) is
F
and convert-to is "All float types": Change precision³³Converts from the current precision available on the evaluation stack to the precision specified by the instruction. If the stack has more precision than the output size the conversion is performed using the IEC 60559:1989 “round-to-nearest” mode to compute the low order bit of the result.
So in this context you should read conv.r8
as "Convert from unspecified floating-point format to double
" rather than "Convert from double
to double
". (Although in this case, we can be pretty sure that F
on the evaluation stack is already double
precision since it's from a double
argument.)
So in summary:
- The .NET Runtime has a
float64
type, but only for storage purposes. - For evaluation purposes (and passing arguments), a precision-unspecified
F
type is must be used instead. - This means that sometimes an "unnecessary" explicit cast to
double
is actually changing the precision of an expression. - The C# compiler doesn't know whether or not it will matter so it always emits the conversion from
F
tofloat64
. (However the JIT does, and in this case will optimize away the cast at runtime.)
QUESTION
I would like check no null parameters are assigned to record fields and let the properties have comments. I have found out the following arrangement does the trick for comments, but I lack ideas to check for null parameters without turning this record into a class.
So, a question: Is it possible to check during runtime that nulls won't be assigned to record fields? If so, how could one do it while still using records?
...ANSWER
Answered 2021-Aug-24 at 23:30You have to handle checks during inline assignment, as you've already discovered in your gist.
One possibility is to call an extension method to wrap any behavior.
Community Discussions, Code Snippets contain sources that include Stack Exchange Network
Vulnerabilities
No vulnerabilities reported
Install SharpLab
Support
Reuse Trending Solutions
Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from over 650 million Knowledge Items
Find more librariesStay Updated
Subscribe to our newsletter for trending solutions and developer bootcamps
Share this Page