10

While coding, a discrepancy surfaced. Normally while coding simple methods or constructors I often utilize the expression body technique. However, when I produce the following:

public class Sample : ISample
{
     private readonly IConfigurationRoot configuration;

     public Sample(IConfigurationRoot configuration) => this.configuration = configuration;
}

The code appears to be valid, Visual Studio and compile both work. The issue though comes if inside that same class, I go to use the configuration variable. It produces "A field initializer cannot reference a non static field initializer."

That syntax usage that produced:

var example = configuration.GetSection("Settings:Key").Value;

However, if I leave the snippet above this and modify to a block body. Visual Studio no longer freaks out, why would an expression body cause such a peculiar error? While the block body works correctly with snippet above?

public class Sample : ISample
{
     private readonly IConfigurationRoot configuration;

     public Sample(IConfigurationRoot configuration)
     {
           this.configuration = configuration;
     }
}

public class ApplicationProvider
{
     public IConfigurationRoot Configuration { get; } = CreateConfiguration();

     public IServiceProvider BuildProvider()
     {
         var services = new ServiceCollection();
         DependencyRegistration(services);

         return services.AddLogging().BuildServiceProvider();
     }

     private IConfigurationRoot CreateConfiguration() => new ConfigurationBuilder()
     .SetBasePath(AppContext.BaseDirectory)
     .AddJsonFile("appsettings.json")
     .Build();

     private void DependencyRegistration(this IServiceCollection services)
     {
          services.AddSingleton(_ => Configuration);
          // All other dependency registration would also go here.
     }
}

public static IServiceProvider ServiceProvider { get; } = new ApplicationProvider().BuildProvider();

I would have an interface for class, then instantiate by pulling from the provider.

ISample sample = ServiceProvider.GetServices<ISample>();
Nkosi
  • 235,767
  • 35
  • 427
  • 472
Greg
  • 11,302
  • 2
  • 48
  • 79
  • 1
    @CalC Weird right? I'm trying to dig into the Microsoft Dependency Injection Framework for Core, thinking it might be there or in another location. But no matter what I do, that error appears inside this core 2.0 application. – Greg Nov 29 '17 at 23:59
  • 1
    Can you add more information showing how you create an instance of the Sample class? – Tyler Stahlhuth Nov 30 '17 at 02:03
  • Please show a [mcve]. The code you've shown should be fine *in a method*. If you're trying to declare a field, you can't declare it with `var` anyway. – Jon Skeet Nov 30 '17 at 10:15
  • @JonSkeet I'm confused by the `var` comment, the example I have with a `var` is trying to read the field to retrieve the value. Not per se use. Could you clarify please? – Greg Nov 30 '17 at 15:50
  • It's trying to declare a variable called `example`, which you can't do using var if you're trying to make that variable a field. Basically, we're guessing what your code really looks like because you haven't provided us with a [mcve]. It's easy to stop the speculation: provide a complete example. – Jon Skeet Nov 30 '17 at 15:52
  • @Greg For example, I tried to replicate the issue last night. https://chat.stackoverflow.com/transcript/message/40245623#40245623 Using DotNetFiddle and the Roslyn compiler, I was able to get similar code to run without issue. However, I completely assumed the `var example` line was a member function or something similar. Also, if you are using a framework to perform the dependency injection for you -- as suggested by your comments -- that is important to know. – Tyler Stahlhuth Nov 30 '17 at 16:15
  • I've updated, it is Asp.Net Core 2.0 utilizing all of the new Core Microsoft.Extensions. – Greg Nov 30 '17 at 17:22
  • @Greg Does Sample implement ISample? Assuming it does. Is that class definition located in a class? Otherwise, `public static IServiceProvider ServiceProvider { get; } = new ApplicationProvider().BuildProvider();` doesn't work. – Tyler Stahlhuth Nov 30 '17 at 17:32
  • @TylerStahlhuth Yes, I updated question. – Greg Nov 30 '17 at 17:47
  • @Greg I see a lot of problems with the code you provided, but am still futzing with trying to get AspNetCore to install so I am unable to test it. Are you sure the code provided compiles? – Tyler Stahlhuth Nov 30 '17 at 19:02
  • I ask because you have a non-static extension method in a non-static class. – Tyler Stahlhuth Nov 30 '17 at 19:12
  • @TylerStahlhuth I may have made typos, I did it really quick and a system went down, so I've been distracted. I'll fix in a bit. The `static` is in a whole different class. – Greg Nov 30 '17 at 19:21
  • @Greg This Gist works just fine when I created a Asp project and used the classes without anything else going on. https://gist.github.com/anonymous/a9f7a9a85399a6f6e323896e737608b5 – Tyler Stahlhuth Nov 30 '17 at 20:33
  • @TylerStahlhuth Hm, weird. I wonder why Visual Studio flags. – Greg Nov 30 '17 at 21:25
  • @Greg Wait, it flags it? Does it actually build? Are you sure that error message isn't `A field initializer cannot reference the non-static field, method, or property` If so, it's this line that is the problem: `public IConfigurationRoot Configuration { get; } = CreateConfiguration();` – Tyler Stahlhuth Nov 30 '17 at 21:40
  • @TylerStahlhuth That line has been popping out at me. When I have a chance I'll let you know. – Greg Nov 30 '17 at 21:44
  • @Greg The reason my version works is because I made the CreateConfiguration method static. – Tyler Stahlhuth Nov 30 '17 at 21:45

0 Answers0