Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Champion "Support extension methods everywhere" #301

Closed
5 tasks
gafter opened this issue Mar 20, 2017 · 5 comments
Closed
5 tasks

Champion "Support extension methods everywhere" #301

gafter opened this issue Mar 20, 2017 · 5 comments

Comments

@gafter
Copy link
Member

gafter commented Mar 20, 2017

  • Proposal added
  • Discussed in LDM
  • Decision in LDM
  • Finalized (done, rejected, inactive)
  • Spec'ed

See also dotnet/roslyn#4565
I've labeled this "Proposal Champion" because it has been triaged by the LDM, but we don't actually have a champion at this point.

@TylerBrinkley
Copy link

See also dotnet/roslyn#16271

@SomeoneIsWorking
Copy link

We decided it would be easier on both programmers and the compiler if we limit the number of places that you have to look for extension methods.

If this is an issue it can be made to accept only private methods for non-static classes.
I wish to be able to build fluent code that will only run inside the class.

@stamminator
Copy link

stamminator commented Jul 15, 2022

Not being able to create extension methods in non-static classes prevents me from using dependency-injected logging inside the extension methods. This makes unit testing difficult and forces me to break things out into services, which adds more complexity than is called for.

Being able to do this would make things much simpler:

public class ModelConversionExtensions
{
    private readonly ILogger<ModelConversionExtensions> _logger;
    public ModelConversionExtensions(ILogger<ModelConversionExtensions> logger) => _logger = logger;

    public static DataModel? ConvertToDataModel(this ViewModel vm)
    {
        try
        {
            return new DataModel() { foo_bar = vm.FooBar };
        }
        catch
        {
            _logger.LogError($"Could not convert {nameof(ViewModel)} with Id of {vm.Id} to {nameof(DataModel)}");
            return null;
        }
    }
}

@HaloFour
Copy link
Contributor

@stamminator

Not being able to create extension methods in non-static classes prevents me from using dependency-injected logging inside the extension methods.

A static member cannot access instance members without an instance. You cannot accomplish what you're describing without some kind of global state, which is pretty much faux pas in a dependency/unit paradigm. However, you could easily accomplish it via:

public static class ModelConversionExtensions
{
    private static ILogger<ModelConversionExtensions> _logger = SomeDefaultLogger;

    public static void RegisterLogger(ILogger<ModelConversionExtensions> logger) => _logger = logger;

    public static DataModel? ConvertToDataModel(this ViewModel vm)
    {
        try
        {
            return new DataModel() { foo_bar = vm.FooBar };
        }
        catch
        {
            _logger.LogError($"Could not convert {nameof(ViewModel)} with Id of {vm.Id} to {nameof(DataModel)}");
            return null;
        }
    }
}

@stamminator
Copy link

@HaloFour You're totally right, that's my bad. Thanks for the suggestion. In your example, what does SomeDefaultLogger consist of, a global static logger? With the idea being that it needs something to start with, but ideally RegisterLogger should be getting called on app startup with DI?

@333fred 333fred closed this as not planned Won't fix, can't repro, duplicate, stale Dec 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants