Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用非静态类包装静态类_C#_Oop_Static Classes - Fatal编程技术网

C# 用非静态类包装静态类

C# 用非静态类包装静态类,c#,oop,static-classes,C#,Oop,Static Classes,我在看一个项目,发现了一些非常奇怪的东西 有一个静态类,它有一组方法,其中每个方法都对远程服务器进行调用 模板看起来有点像这样: public static class DAI public static ResponseObject ExecStatement(string db, string sql) { { ... } } public static DataSetResponseObject GetDataSet(string db

我在看一个项目,发现了一些非常奇怪的东西

有一个静态类,它有一组方法,其中每个方法都对远程服务器进行调用

模板看起来有点像这样:

public static class DAI

    public static ResponseObject ExecStatement(string db, string sql)
    {
         { ... }
    }

    public static DataSetResponseObject GetDataSet(string db, string sql)
    {
         { ... }
    }

    public static DataTableResponseObject GetDataTable(string db, string sql)
    {
         { ... }
    }
}
但是项目中没有任何地方调用这个类。相反,它调用非静态类容器

public class ExecSP : IExecSP
{
    string _db;
    public ExecSP(string db)
    {
        _db = db;
    }

    public ResponseObject OutputAsResponseObject(string sql)
    {
         return DAI.ExecStatement(_db, sql);
    }

    public ResponseObject OutputAsDataSet(string sql)
    {
         return DAI.GetDataSet(_db, sql);
    }

    public ResponseObject OutputAsDataTable(string sql)
    {
         return DAI.GetDataTable(_db, sql);
    }
}
现在,我认为唯一的两个优点是,当包装在非静态容器中时,术语更清晰,并且传递的参数更少


但我想知道这是否是一个好主意,通过设计将静态类包装为非静态类?如果有的话,还有哪些其他原因?因为我认为创建一个static并调用它是可以的。但是这个项目有意地总结了所有静态类;我不知道为什么。

就我个人而言,我永远不会这样做,我要做的是使用.NET依赖注入框架,如Ninject或Unity,以便在创建对象时将必要的引用注入到对象中。这样做有很多好处……对于初学者来说,您可以创建您的单例对象,而不必实际使用静态成员,并且您可以更好地控制它们的生命周期。如果你想做单元测试(你应该这么做),那么用模拟对象替换你的单例是很简单的,如果您稍后决定可能单例不是最佳的设计选择,那么插入一个范围为其他对象(如主父视图模型等)的对象是很简单的。您正在查看的项目可能正在使用该中间类来实现我所说的一些功能,但它永远不会像进行适当的依赖项注入那样灵活或干净。

我过去做过这样的事情最常见的原因是,如果静态方法由第三方库提供(即,我没有编写它),但我不想编写直接依赖于该库的代码。在这种情况下,我将编写自己的类,并让它采用直接依赖关系


假设我使用一个接口(或类似于您的示例中的某个接口),那么如果我决定使用另一个库,我可以编写另一个实现相同接口的类,并在运行时交换具体类(使用依赖项注入之类的方法).

添加的类
ExecSP
没有任何好处。这两种方法都传入一个db字符串和一个sql字符串。我想象db字符串是数据库实例的某种连接字符串,sql是该实例要执行的原始sql字符串。在这种情况下,最好直接调用
DAI
,没有理由使用包装器类

从设计过程来看,这是紧密耦合。我们可能希望通过创建一个实例,然后针对抽象运行一个命令,而不是传递连接字符串/sql语句,从而消除数据库(IDatabase)

Psudeo代码:

IDatabase dbInstance =  new DatabaseCreator(db);
dbInstance.Execute(sql); 
那么,数据库是否是SQL Server、Oracle等就无关紧要了


抽象有助于测试。例如,在单元测试项目中,我可以编写自己的IDatabase实现,甚至不使用数据库。如果没有实际的数据库实例,我不确定您将如何测试它。如果我编写自己的测试实例,我可以删除该外部依赖项。

在我看来,他们试图使对象可注入,以便使代码更易于测试和以后修改

查看此帖子:

这是一种标准模式。 -包装一组更复杂的方法以隐藏其复杂性,例如一组只通过抛出异常返回错误的方法。 -处理包装器方法中的错误、异常等 -将方法设置为静态,以防止派生方法(如executeQueryByInt、executeQueryByLong、executeQueryByString等)的乘法。。。 -限制对SQL处理框架代码的引用的传播仅限于包装的方法 -重要信息:在使用第三方静态库时,有一个单独的地方记录如何调用、错误、特殊情况、bug解决方法

对于单元测试,单元测试应该实现一个短包装器类,它只通过对静态类的调用来传递

无论多么简单,都不需要再增加一层复杂性来适应任意模式或对代码进行云计算。您的生产代码不应该仅在单元测试中使用额外代码的情况下实现该代码

通常在项目中单独包装库或nuget包,这样多解决方案项目就不会有几十个对第三方包的包引用

奇怪的是,桶的概念有多大角度,而.net内核却没有;一旦项目数量超过10个,并且解决方案的使用期限超过2年,您就可以进入Nuget Package h*ll


在多次重组1000000多行.net解决方案之后,静态方法和静态类使代码更容易在更大的上下文中移动。哪些最佳实践在较小的项目中可以很好地扩展,但在1000000多个线路系统中却无法很好地扩展。这是一种不同于玩具项目和短博客的方法。这是关于能够看到调用了什么代码以及在哪里调用代码,这样重构、简化就更容易了

首先要了解的是,没有“静态对象”或“非静态对象”这样的东西。有静态方法、静态类、静态变量等,但没有静态对象。你刚才讨论的设计听起来确实很奇怪。谢谢你的提醒!我刚刚做了编辑如果这些课程的原作者仍然在场,问他们为什么这样做是一个好主意。可悲的是,这已经存在了4年,从那时起,传统就是采用这种方法。没有人真正告诉我为什么我们要这么做。在fa中