You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

设计接口/基类:无需强制转换访问基类列表的SOLID方案

问题与解决方案

初始测试代码

using System.Text;

namespace Lib1;

public class WriteOnlySqlFile : BaseFile, IWriteOnlySqlFile
{
    public string SaveText()
    {
        Console.WriteLine("{0}, {1}, save text sql file", FilePath, FileText);
        return "";
    }
}

public class ReadOnlySqlFile : BaseFile, IReadOnlySqlFile
{
    public string LoadText()
    {
        Console.WriteLine("{0} {1}, readonly sql file loading text here!", FilePath, FileText);
        return "";
    }
}

public interface IReadOnlySqlFile
{
    public string LoadText();
}

public interface IWriteOnlySqlFile
{
    public string SaveText();
}

public abstract class BaseFile
{
    public string FilePath { get; init; } = string.Empty;
    public string FileText { get; init; } = string.Empty;
}

public static class SqlFileManager
{
    public static string GetTextFromFiles(List<IReadOnlySqlFile> readOnlySqlFiles)
    {
        StringBuilder objStrBuilder = new StringBuilder();
        foreach (var objFile in readOnlySqlFiles)
        {
            objStrBuilder.Append(objFile.LoadText());
        }

        return objStrBuilder.ToString();
    }

    public static void SaveTextIntoFiles(List<IWriteOnlySqlFile> writeOnlySqlFiles)
    {
        foreach (var objFile in writeOnlySqlFiles)
        {
            objFile.SaveText();
        }
    }
}

需求与问题

需要将SqlFileManager改为非静态类,使其持有BaseFile类型的实例集合,遍历集合时避免强制类型转换,以符合SOLID原则的方式调用对应读写方法。当前尝试的代码依赖具体类的类型转换,不符合面向抽象的设计原则。

符合SOLID的解决方案

利用面向接口编程和LINQ的OfType<T>方法,筛选出实现对应接口的实例,直接调用接口方法,无需转换具体类:

using System.Text;
using System.Linq;

namespace Lib1;

// WriteOnlySqlFile、ReadOnlySqlFile、相关接口、BaseFile 保持原有代码不变

public class SqlFileManager
{
    private readonly List<BaseFile> _sqlFiles;

    public SqlFileManager(List<BaseFile> files)
    {
        _sqlFiles = files ?? throw new ArgumentNullException(nameof(files));
    }

    public string GetTextFromFiles()
    {
        StringBuilder strBuilder = new StringBuilder();
        // 筛选实现IReadOnlySqlFile的实例,直接调用接口方法
        foreach (var readOnlyFile in _sqlFiles.OfType<IReadOnlySqlFile>())
        {
            strBuilder.Append(readOnlyFile.LoadText());
        }
        return strBuilder.ToString();
    }

    public void SaveTextIntoFiles()
    {
        // 同理筛选实现IWriteOnlySqlFile的实例
        foreach (var writeOnlyFile in _sqlFiles.OfType<IWriteOnlySqlFile>())
        {
            writeOnlyFile.SaveText();
        }
    }
}

方案优势

  • 依赖倒置原则:依赖抽象接口而非具体实现类,后续新增如ReadWriteSqlFile这类同时实现两个接口的类时,无需修改SqlFileManager的代码
  • 无强制转换:通过OfType<T>安全筛选符合条件的实例,避免类型转换带来的空引用或类型转换异常
  • 单一职责原则:SqlFileManager只负责协调文件的读写调度,具体读写逻辑由各自的文件类实现,职责清晰

内容的提问来源于stack exchange,提问作者razlani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 10:50:17