做白酒有没有必要做个网站,网站如何增加流量,网站备案帐号是什么意思,河北省衡水市景县规划网站第1章 接口#xff08;interface#xff09;是什么1.1 定义• 接口是一组“能力”或“契约”的抽象描述#xff0c;只规定“能做什么”#xff0c;不规定“怎么做”。• 在 C# 中#xff0c;接口是一种完全抽象的类型#xff08;fully abstract type#xff09;。
• 关…第1章 接口interface是什么1.1 定义• 接口是一组“能力”或“契约”的抽象描述只规定“能做什么”不规定“怎么做”。• 在 C# 中接口是一种完全抽象的类型fully abstract type。
• 关键词interface。
• 命名规范以大写字母 I 开头如 ILogger、IDisposable。1.2 语法骨架
public interface 接口名
{// 1. 属性数据类型 属性名 { get; set; } // 自动属性写法// 2. 方法返回类型 方法名(参数列表);// 3. 索引器数据类型 this[int index] { get; set; }// 4. 事件event EventHandler 事件名;
}• 成员默认 public不允许显式写 public/private/protected。• 不允许有字段(field) 和 实例构造函数。第2章 实现接口的三种姿势2.1 隐式实现Implicit Implementation
public class FileLogger : ILogger
{public void Log(string message) Console.WriteLine($[File] {message});
}• 类中 public 成员签名与接口成员一致即可。• 通过类变量或接口变量都能调用。2.2 显式实现Explicit Implementation
public class DbLogger : ILogger
{void ILogger.Log(string message) // 无访问修饰符 Console.WriteLine($[DB] {message});
}• 只能“接口变量”调用ILogger log new DbLogger(); log.Log(...)。• 解决“菱形继承”时成员命名冲突。2.3 结构体实现接口
public struct Point : IEquatablePoint
{public int X, Y;public bool Equals(Point other) X other.X Y other.Y;
}• 值类型也可实现接口但注意装箱问题。第3章 接口的进阶特性
interface IRunnable { void Run(); }
interface ILogger { void Log(string msg); }class Job : IRunnable, ILogger
{public void Run() Log(Job is running);public void Log(string msg) Console.WriteLine(msg);
}3.2 接口继承接口
interface IAdvancedLogger : ILogger
{void LogError(Exception ex);
}实现类必须实现全部成员包括继承链。3.3 默认实现C# 8.0
public interface ILogger
{void Log(string message);void LogError(Exception ex) Log($Error: {ex.Message});
}• 实现类不强制实现 LogError。• 解决“接口演化”问题向后兼容。3.4 静态抽象成员C# 11
public interface IFactoryT where T : new()
{static abstract T Create();
}用于泛型数学、泛型工厂等高级场景。第4章 完整案例插件式日志系统4.1 需求• 系统同时支持控制台、文件、数据库三种日志输出。• 可随时插拔新的日志方式。• 调用端面向接口编程不依赖具体实现。4.2 设计定义接口 ILogger三种实现ConsoleLogger、FileLogger、SqlLogger使用“工厂 反射”做插件加载客户端仅依赖 ILogger4.3 代码实现 (1) 接口
public interface ILogger
{void Log(string message);void LogError(Exception ex);
}(2) 控制台实现
public class ConsoleLogger : ILogger
{public void Log(string message) Console.WriteLine($[Console] {DateTime.Now}: {message});public void LogError(Exception ex) Log($ERROR: {ex});
}(3) 文件实现
public class FileLogger : ILogger
{private readonly string _path;public FileLogger(string path) _path path;public void Log(string message) File.AppendAllText(_path, ${DateTime.Now}: {message}\n);public void LogError(Exception ex) Log($ERROR: {ex});
}(4) 工厂简化版
public static class LoggerFactory
{public static ILogger Create(string type, params object[] args){var t Type.GetType(type, true);return (ILogger)Activator.CreateInstance(t, args);}
}(5) 配置文件 appsettings.json
{Logger: {Type: FileLogger,Args: [ app.log ]}
}6 LoggerConfig 的定义
// 通常放在 Models 文件夹或 Config 文件夹下
public class LoggerConfig
{// 对应 JSON 里的 Typepublic string Type { get; set; }// 对应 JSON 里的 Args由于 JSON 里是数组所以用 object[]public object[] Args { get; set; } Array.Emptyobject();
}(7) 客户端
var config JsonSerializer.DeserializeLoggerConfig(File.ReadAllText(appsettings.json));
ILogger logger LoggerFactory.Create(config.Type, config.Args);logger.Log(系统启动);
try { int x 0, y 1 / x; }
catch (Exception ex) { logger.LogError(ex); }• 更换日志方式只需改配置无需改业务代码。第5章 常见误区与最佳实践接口 vs 抽象类• 接口多继承、纯契约、无状态。• 抽象类单继承、可包含状态、可含实现。接口隔离原则ISP• 不要强迫客户依赖它们不用的方法。• 把“胖接口”拆分为多个小接口。命名规范• 接口以 I 开头实现类以接口名去掉 I 为后缀如 SqlLogger : ILogger。显式实现的代价• 调用方必须转换成接口类型降低可读性除非解决冲突否则优先隐式实现。