Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

120
Visualizações
Is there a way to detect a C# 10 breaking change in the resolution for extension methods?

Consider the following code:

using System;

static class Program
{
    public static void Main()
    {
        Test test = new Test();
        test.Method(()=>{});
    }
}

public sealed class Test
{
    public void Method(Delegate _)
    {
        Console.WriteLine("Test.Method(Delegate)");
    }
}

public static class TestExt
{
    public static void Method(this Test self, Action _)
    {
        Console.WriteLine("TestExt.Method(Action)");
    }
}

In C# 9.0 targeting net48, this outputs TestExt.Method(Action)

In C# 10.0 targeting net6.0, this outputs Test.Method(Delegate)

Obviously this is a breaking change because the extension method may execute different code.

My question is: Is there a way to detect this sort of breaking change in the code without inspecting all the code? For example, is there a code analysis rule that we can enable to detect this sort of code?

This change has actually caused a genuine bug in our code base.


Note that this difference in behaviour is only occurring because of changes to the extension method resolution. If instead of an extension method, the method is in the Test class itself then both language versions call Test.Method(Action):

static class Program
{
    public static void Main()
    {
        Test test = new Test();
        test.Method(()=>{});
    }
}

public sealed class Test
{
    public void Method(Delegate _)
    {
        Console.WriteLine("Test.Method(Delegate)"); // Not called by either version.
    }

    public void Method(Action _)
    {
        Console.WriteLine("TestExt.Method(Action)"); // Called by C#9 and C#10.
    }
}

Background information:

This breaking change has bitten us because we have (rightly or wrongly) an extension method for Control.BeginInvoke() along these lines (error handling omitted):

public static void BeginInvoke(this Control control, Action action)
{
    if (control.IsHandleCreated)
        tryBeginInvoke(control, action);
}

This is no longer called for code like:

this.BeginInvoke(() => someMenu.Visible = somethingIsAvailable());

Instead, Control.BeginInvoke(Delegate) is called, which omits the check for control.IsHandleCreated and the tryBeginInvoke() error handling method.

over 4 years ago · Santiago Trujillo
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda