Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • 14:32
    CyrusNajmabadi synchronize #63398
  • 14:29
    CyrusNajmabadi synchronize #63398
  • 14:27
    CyrusNajmabadi commented #63397
  • 14:19
    dotnet-issue-labeler[bot] labeled #63398
  • 14:19
    CyrusNajmabadi review_requested #63398
  • 14:19
    CyrusNajmabadi review_requested #63398
  • 14:19
    CyrusNajmabadi opened #63398
  • 14:12
    dotnet-issue-labeler[bot] labeled #63397
  • 14:12
    84819760 labeled #63397
  • 14:12
    84819760 opened #63397
  • 14:12
    84819760 labeled #63397
  • 13:54
    msftbot[bot] milestoned #63379
  • 13:54

    CyrusNajmabadi on main

    Simplify TypeKind condition Apply suggestions from code rev… Update src/Features/Core/Portab… and 1 more (compare)

  • 13:54
    CyrusNajmabadi commented #63379
  • 13:54
    CyrusNajmabadi closed #63379
  • 13:32
    svick closed #63361
  • 13:32
    svick commented #63361
  • 12:45
    dotnet-issue-labeler[bot] labeled #63396
  • 12:45
    dotnet-issue-labeler[bot] labeled #63396
  • 12:45
    Sergio0694 opened #63396
Yair Halberstadt
@YairHalberstadt
@VBAndCs what matters is which language the foreach is in, not which language has the GetEnumerator
It's a change to the spec for how foreach binds. There's nothing special about the GetEnumerator method. Just C# recognizes certain patterns when lowering foreach and VB a different set.
Antony Male
@canton7
My understanding of the question was that VB did manage to use an extension GetEnumerator, but only when the extension GetEnumerator was written in C#, not in VB?
Yair Halberstadt
@YairHalberstadt
If it did, that would be truly magical
Perhaps little mice sneaking in whilst I was sleeping and writing the code for that.
Mohammad Hamdy Ghanem
@VBAndCs
Seems that vb for each was able to consume C# getEnemurator b4 it was added to C# :). The question is why it can't consume the vb one? This is the code that vb generates:
[StandardModule]
public sealed class Tools
{
    [IteratorStateMachine(typeof(VB$StateMachine_0_GetEnumerator))]
    public static IEnumerable GetEnumerator(this (int, int, int) range)
    {
        VB$StateMachine_0_GetEnumerator vB$StateMachine_0_GetEnumerator = new VB$StateMachine_0_GetEnumerator(-2);
        vB$StateMachine_0_GetEnumerator.$P_range = range;
        return vB$StateMachine_0_GetEnumerator;
    }
}
I can't see what c# generates (except in il which I don't understand).
So, what is wrong with the vb state machine?
Yair Halberstadt
@YairHalberstadt
@VBAndCs I don't understand what you're saying by "Seems that vb for each was able to consume C# getEnemurator b4 it was added to C#"
Antony Male
@canton7
One difference is that it's missing the [Extension] attribute?
Mohammad Hamdy Ghanem
@VBAndCs

@VBAndCs I don't understand what you're saying by "Seems that vb for each was able to consume C# getEnemurator b4 it was added to C#"

Try it on yout machine. The getenumerator extension method works in vb when it is written in C# but doesn't work when it is written in VB! For Each in vb doesn what foreach in c# does in this matter, but seems the difference is in the generated state machine in both languages, or the way that Yield is implemented in both. Maybe it is a different attribute sued or a missing one. Seems something that can be fixed in vb to have the same functionality as c#.

Mohammad Hamdy Ghanem
@VBAndCs

One difference is that it's missing the [Extension] attribute?

this is the code I get back from ILSpy. I use the Extension attribute in the code as I posted before, and I show you that calling the .GetEnumerator explicitly works only for the one written in VB not C#.

Mohammad Hamdy Ghanem
@VBAndCs
Another thing to fix in C#: this code gives an error:
var e = (1, 2).GetEnumerator();
although I defined a GetEnumerator extension method!
Making it works on foreach is nice, but it should also work everywhere.
@VBAndCs Note that your extension method is on (int, int, int), but you're calling it on (int, int) just above. Those are different types
Aha, looking more closely at your screenshots, you're mixing up IEnumerable and IEnumerator.
  1. Your C# method returns IEnumerator
  2. This image image.png shows VB is complaining when you have a ForEach loop over an IEnumerator
  3. Your VB extension method returns IEnumerable, not IEnumerator (so it's different to the C# version)
  4. This image image.png shows VB is fine when you have a ForEach loop over an IEnumerable
Antony Male
@canton7
Fix up your VB extension method, and it works fine: https://dotnetfiddle.net/CQwNgG
@YairHalberstadt Looks like those mice were hard at work
Mohammad Hamdy Ghanem
@VBAndCs
My bad :D. But nice surprise that VB supports it :)
Seems I used the auto completion without paying attention. The two words are visually so close :)
But since when this is working in VB?
Mohammad Hamdy Ghanem
@VBAndCs

@VBAndCs Note that your extension method is on (int, int, int), but you're calling it on (int, int) just above. Those are different types

I have a two-item version.

using System;
using System.Collections;
using System.Runtime.CompilerServices;

foreach (int i in 20..10)
    Console.WriteLine(i);

foreach (int i in (10, -10))
    Console.WriteLine(i);

foreach (int i in (-10, 10, 3))
    Console.WriteLine(i);


public static class Extensions
{
    public static IEnumerator GetEnumerator(this System.Range range)
    {
        int start = range.Start.Value;
        int end = range.End.Value;
        if (end > start)
            for (int i = start; i <= end; i++)
                yield return i;
        else
            for (int i = start; i >= end; i--)
                yield return i;
    }

    public static IEnumerator GetEnumerator(this System.ValueTuple<int, int> range)
    {
        int start = range.Item1;
        int end = range.Item2;
        if (end > start)
            for (int i = start; i <= end; i++)
                yield return i;
        else
            for (int i = start; i >= end; i--)
                yield return i;
    }

    public static IEnumerator GetEnumerator(this System.ValueTuple<int, int, int> range)
    {
        int start = range.Item1;
        int end = range.Item2;
        int step = range.Item3;

        if (step > 0)
            for (int i = start; i <= end; i+=step)
                yield return i;
        else
            for (int i = start; i >= end; i += step)
                yield return i;
    }

}
Antony Male
@canton7
... and that works fine when you do var e = (1, 2).GetEnumerator()
Joe4evr
@Joe4evr

VB is complaining when you have a ForEach loop over an IEnumerator

of note, C# would do the same thing - there's an open-standing request to allow foreach-ing over an enumerator

Yair Halberstadt
@YairHalberstadt
@canton7 maybe it always worked in VB... I definitely didn't add it.
Mohammad Hamdy Ghanem
@VBAndCs
Thanks. This was helpful :). At least we discovered something new in VB.NET :).
Michael Fry
@nth-commit
Does anyone know of any guides which describe the relationship/non-relationship between the semantic model and System.Reflection? It's something I bump into all the time and haven't quite taken the time to understand. I am super familiar with navigating around System.Reflection and doing dynamic type stuff. Not so familiar with navigating around the semantic model (e.g. Compilation, ITypeSymbol). It would be nice if there was something I could read through which would help relate my familiarity with the former to the latter.
CyrusNajmabadi
@CyrusNajmabadi
There's no API relation. In that there no strong way to tie the entities from one to another.
However, there is a weak relation. System.Reflection allows for an API for a few purposes: introspecting metadata and querying against live values at runtime.
The Roslyn symbol model rejects reflects the static semantics of code at compile time.
There are many similar ideas in both.
For example PropertyInfo in reflection, and IPropertySymbol in Roslyn.
Roslyn has no runtime querying concept though*. It's all (mostly) about the information at compile time.
Michael Fry
@nth-commit

Thanks :)

Yeah I understand. Although a large portion of System.Reflection is to do with statically available info (obviously I don't expect roslyn to be able to give me runtime values if there isn't a program running, so there's no representation of CreateInstance, SetValue, GetValue etc.).

For example PropertyInfo in reflection, and IPropertySymbol in Roslyn

This is the stuff I want to hear about :D. I just want to know if these kinds of relationships are documented somewhere - and is it a value that the roslyn team hold or is any symmetry between the APIs incidental?

CyrusNajmabadi
@CyrusNajmabadi
Both? :-)
Both the language and the bcl need to represent things from metadata. And metadata in c# is produced from source. So there's are just common ways of representing those entities.
timiil
@timiil
Is there any opensource solution that use Roslyn to 'obfuscation' or 'protect' .NET PE ?
Bernd Baumanns
@bernd5
roslyn only emits IL - but it doesn't modify it
Yair Halberstadt
@YairHalberstadt

IsNullableTypeOrTypeParameter (https://sourceroslyn.io/#Microsoft.CodeAnalysis.CSharp/Symbols/TypeSymbolExtensions.cs,113) checks if a constraint type is a nullable type.

But how is this ever possible since structs can't be constraints? Is it only if the constraint is defined in a different language?

Mohammad Hamdy Ghanem
@VBAndCs
Languages are getting more complex (esp C#). It would be helpful for beginners and maybe old dves as mine if ther is an action named explain or whatever to lower a code block to a classic simple C#/VB code and show it in a readoly code window. Pattern matching expressions are in top of things that may need explanation. I may go far and say every new concept since Roslyn can be considered hard and nee to be explained. This can be a useful educational feature, and ease the pain for new team members that joins a large project. VS offers to simplify expressions which in most cases means shorten them into a complex modern syntax! We may need an action on the opposite direction. This seems a lot of work, but it can make use of the Roslyn code itself if it lowers these statements.
timiil
@timiil

roslyn only emits IL - but it doesn't modify it

i am looking for some 'name obfuscation Analyzer' or 'string encrypt Analyzer' ... 'XXX protect sourcecode Analyzer' things that build from roslyn...

Bernd Baumanns
@bernd5
if you have the csharp source you can write some rewriters which renames locals and non public types / methods
something like this
Bernd Baumanns
@bernd5
I would avoid arabic chars
timiil
@timiil
:)
Bernd Baumanns
@bernd5
I would name them a1, a2, a3....
but unicode should work, too.