在非静态构造函数中设置静态字段 |为什么这行得通? | C#
Setting Static Field in Non-static Constructor | Why does this work? | C#
在此应用程序中,我们将 JUST.net 与自定义函数一起使用。 JUST.net 中的自定义函数必须是静态方法。我创建了一个定义所有静态函数的 class;这些函数通过反射注册到 JUST.net 上下文。我需要在这些静态函数中包含日志记录,以防其中一个映射失败。
为了完成这个,我们有这样的代码:
public class Transformations
{
private static ILogger<Transformation> _logger;
public Transformations(ILogger<Transformations> logger)
{
_logger = logger;
}
public static string MapAddress(string? streetNumber, string? streetName)
{
if(string.IsNullOrEmpty(streetNumber)
{
_logger.LogError("The property was not provided.");
}
// etc...
}
// etc...
}
当我从测试中调用它时,如果我实例化 class 并静态引用函数,记录器就会工作。如果我不实例化 class 并静态引用方法,记录器将不起作用。
即:
public class AddressUnitTest
{
private readonly Transformations _transformations;
public AddressUnitTest()
{
var serilog = new LoggerConfiguration().WriteTo.Console().CreateLogger();
var loggerFactory = new LoggerFactory().AddSerilog(serilog);
var logger = loggerFactory.CreateLogger<Transformations>();
_transformations = new Transformations(logger);
}
[Fact]
public void Address(string? streetNumber, string? streetName)
{
var actualValue = Transformations.MapAddress(streetNumber, streetName);
// etc...
}
}
鉴于您不能使用 _transformations.MapAddress()
并且必须静态引用这些方法,即:Transformation.MapAddress()
,当我实例化一个看似无关的版本时,为什么记录器可以工作?
也就是说,为什么设置 _transformations = new Transformations(logger);
会授予 Transformations.MapAddress()
访问记录器的权限?
似乎有效;我只是不明白为什么。有没有更好的方法来完成这个?
原因是 _logger
字段唯一一次被初始化为任何东西是在 class 构造函数中。
最好编写一个静态方法来初始化记录器,并使您的整个 class 静态(这样它的所有成员都必须是静态的)这样就不会出现这种混淆:
public static class Transformations
{
private static ILogger<Transformation> _logger;
public static void InitialiseLogger(ILogger<Transformations> logger)
{
_logger = logger;
}
public static string MapAddress(string? streetNumber, string? streetName)
{
if(string.IsNullOrEmpty(streetNumber)
{
_logger.LogError("The property was not provided.");
}
// etc...
}
// etc...
}
在您的单元测试中,应该可以有一个启动方法为所有单元测试调用一次 Transformations.InitialiseLogger()
,这样您就不必在每个测试方法中重复它。 (或者其他方式——我不熟悉 xUnit 是如何做到这一点的。)
在此应用程序中,我们将 JUST.net 与自定义函数一起使用。 JUST.net 中的自定义函数必须是静态方法。我创建了一个定义所有静态函数的 class;这些函数通过反射注册到 JUST.net 上下文。我需要在这些静态函数中包含日志记录,以防其中一个映射失败。
为了完成这个,我们有这样的代码:
public class Transformations
{
private static ILogger<Transformation> _logger;
public Transformations(ILogger<Transformations> logger)
{
_logger = logger;
}
public static string MapAddress(string? streetNumber, string? streetName)
{
if(string.IsNullOrEmpty(streetNumber)
{
_logger.LogError("The property was not provided.");
}
// etc...
}
// etc...
}
当我从测试中调用它时,如果我实例化 class 并静态引用函数,记录器就会工作。如果我不实例化 class 并静态引用方法,记录器将不起作用。
即:
public class AddressUnitTest
{
private readonly Transformations _transformations;
public AddressUnitTest()
{
var serilog = new LoggerConfiguration().WriteTo.Console().CreateLogger();
var loggerFactory = new LoggerFactory().AddSerilog(serilog);
var logger = loggerFactory.CreateLogger<Transformations>();
_transformations = new Transformations(logger);
}
[Fact]
public void Address(string? streetNumber, string? streetName)
{
var actualValue = Transformations.MapAddress(streetNumber, streetName);
// etc...
}
}
鉴于您不能使用 _transformations.MapAddress()
并且必须静态引用这些方法,即:Transformation.MapAddress()
,当我实例化一个看似无关的版本时,为什么记录器可以工作?
也就是说,为什么设置 _transformations = new Transformations(logger);
会授予 Transformations.MapAddress()
访问记录器的权限?
似乎有效;我只是不明白为什么。有没有更好的方法来完成这个?
原因是 _logger
字段唯一一次被初始化为任何东西是在 class 构造函数中。
最好编写一个静态方法来初始化记录器,并使您的整个 class 静态(这样它的所有成员都必须是静态的)这样就不会出现这种混淆:
public static class Transformations
{
private static ILogger<Transformation> _logger;
public static void InitialiseLogger(ILogger<Transformations> logger)
{
_logger = logger;
}
public static string MapAddress(string? streetNumber, string? streetName)
{
if(string.IsNullOrEmpty(streetNumber)
{
_logger.LogError("The property was not provided.");
}
// etc...
}
// etc...
}
在您的单元测试中,应该可以有一个启动方法为所有单元测试调用一次 Transformations.InitialiseLogger()
,这样您就不必在每个测试方法中重复它。 (或者其他方式——我不熟悉 xUnit 是如何做到这一点的。)