验证基于Action<ITest>委托的配置扩展实现是否正确
Is My Use of
Action<ITest> Delegate Correct? Great news—your implementation of Action<ITest> here is totally correct! This pattern is widely used in .NET for building flexible, extensible configuration APIs (you’ll spot it in frameworks like ASP.NET Core for setting up hosts, services, etc.), so you’re absolutely on the right track.
Let’s break down why your approach works so well:
- Optional extension point: By making the
Action<ITest>parameter optional (with a defaultnullvalue), you let callers choose between using just the default configuration or adding their own custom settings. The?.Invoke()syntax safely skips executing the delegate if it’s null, avoiding annoying null reference exceptions. - Interface-driven flexibility: Using
Action<ITest>instead ofAction<ConfigClass>follows the dependency inversion principle—your delegate depends on an abstraction (the interface) rather than a concrete class. This makes it easy to swap out configuration implementations later without changing the coreDoSomeConfigurationmethod. - Clean separation of concerns: Your default configuration logic lives inside
DoSomeConfiguration, while callers only handle their custom additions. This keeps the core logic focused and extensions isolated.
Small suggestions to polish your code:
- Split responsibilities in
SetConfig: Right now, this method both adds configurations and prints them. It’s better to separate these actions for better single responsibility:- Rename the interface method to
AddConfigurationfor clearer intent. - Create a separate
PrintConfigurationsmethod to handle output.
- Rename the interface method to
- Encapsulate the configuration collection: Exposing
MyConfigurationsas aList<string>lets external code modify it directly. Instead, expose it as anIEnumerable<string>to keep control over how items are added. - Add XML documentation: This helps other developers (or future you) understand how to use
DoSomeConfigurationat a glance.
Revised code incorporating these tips:
using System.Collections.Generic; using System; class Program { static void Main(string[] args) { // Add custom configuration via Action delegate Program.DoSomeConfiguration(cfg => cfg.AddConfiguration("New Config")); // Use default configuration only // Program.DoSomeConfiguration(); } /// <summary> /// Runs default configuration and allows optional custom configuration via an Action delegate. /// </summary> /// <param name="customizeConfig">Optional action to add custom configuration settings.</param> public static void DoSomeConfiguration(Action<ITestConfig> customizeConfig = null) { var config = new ConfigClass(); config.AddConfiguration("Old Config"); // Apply custom configuration if provided customizeConfig?.Invoke(config); config.PrintConfigurations(); } } public interface ITestConfig { /// <summary> /// Adds a new configuration setting. /// </summary> /// <param name="config">The configuration string to add.</param> void AddConfiguration(string config); } public class ConfigClass : ITestConfig { private readonly List<string> _configurations = new List<string>(); // Expose read-only access to configurations public IEnumerable<string> Configurations => _configurations; public void AddConfiguration(string config) { if (!string.IsNullOrWhiteSpace(config)) { _configurations.Add(config); } } public void PrintConfigurations() { Console.WriteLine("**************************************"); foreach (var config in _configurations) { Console.WriteLine($"config {config}"); } } }
Overall, your original code is solid—you’ve correctly implemented a common and powerful .NET pattern. Keep experimenting with delegates and interfaces like this, they’re key tools for building flexible, maintainable code!
内容的提问来源于stack exchange,提问作者KiddoDeveloper
相关产品推荐
相关产品推荐

