Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.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#_Extension Methods - Fatal编程技术网

C# 这种技术有名字吗?它是一种代码气味吗?

C# 这种技术有名字吗?它是一种代码气味吗?,c#,extension-methods,C#,Extension Methods,我以前见过类似于下面的代码,它导致一种“扩展访问方法”被添加到对象中。扩展方法将仅作为一个方法出现在intellisense中,但选中时,intellisense将与“manager”类中定义的所有方法一起出现。这似乎是一种很好的方法,可以组织一组类似的功能并分离主要对象的主要智能感知 因此,我想知道这种技术是否有某种常用的名称,以及它是否被认为是一种代码气味(除了主要对象承担太多责任和变得太大的一般问题之外) 上述代码将按如下方式使用: var myString = "the string";

我以前见过类似于下面的代码,它导致一种“扩展访问方法”被添加到对象中。扩展方法将仅作为一个方法出现在intellisense中,但选中时,intellisense将与“manager”类中定义的所有方法一起出现。这似乎是一种很好的方法,可以组织一组类似的功能并分离主要对象的主要智能感知

因此,我想知道这种技术是否有某种常用的名称,以及它是否被认为是一种代码气味(除了主要对象承担太多责任和变得太大的一般问题之外)

上述代码将按如下方式使用:

var myString = "the string";
var twiceLength= myString.Operations().GetTwiceLength();
为愚蠢的功能道歉。这是从一个实际推荐该技术的示例中借用的,经过修改以保护潜在的罪犯。

这看起来像

适配器是一种结构设计模式,允许具有不兼容接口的对象进行协作[]

让我解释一下为什么我认为这适用于这里:

C#中的扩展方法只是常规的静态方法,只有一点点语法糖分。函数第一个参数的
this
关键字允许您调用它,就好像它是该类型上的实例方法一样。但您也可以像调用常规静态方法一样调用它:

StringExtensions.Operations("your string").CallMethtod();
查看
操作
实现:

public static StringManager Operations(this String value)
{
    return new StringManager(value);
}
我们可以看到,这是一个普通的旧版本,它返回Manager类(=适配器)的一个实例。这相当于直接创建apapter实例(但实际上是有利的,因为它隐藏了创建新实例的“方式”。例如,您可以使用池和重用现有实例):

Manager类调整
string
类型/接口以与其他接口兼容,提供所有“管理方法”,而不是原始的string方法。要使“适配器”显式可见,可以使用中间变量(用于演示):

var originalString=“您的字符串”; var adaptedString=新StringManager(原始字符串); adaptedString.CallMethod()

这是一种代码气味吗?我不这么认为,不一定。您只是将一个类的接口适配到另一个接口(string接口到StringManager接口)。有人可能会争辩说,不应该在类名中使用“Manager”,因为它没有添加任何有用的上下文,基本上可能意味着任何东西。你的所有课程迟早都会成为某种管理者、服务或管理者服务


对于所有模式:在它们有意义并提供好处时使用它们。不要过度使用它们:不要仅仅为了使用模式而使用设计模式。有时甚至最好不要使用模式,即使有模式存在,或者故意引入气味(使用代码注释解释为何以这种方式实现某些东西)。使用明智的判断。

这根本不是一种模式。因为一次只能执行一个操作,所以最好将扩展方法挂起,完全避免使用Manager类。您可能想引用原始源代码,因为我怀疑您的示例在翻译过程中可能丢失了一些内容。@RobertHarvey-嗯,您可以执行两个操作,如果您想将它们添加到StringManager类中,可能会执行数百个操作,所有操作都是在主对象的单个“operations()”方法后面组织的。我只是举了一个例子,叫他们其中的一个,但是你不能把他们连在一起。这里唯一的好处是Intellisense,通过字符串扩展,您仍然可以获得它。我是说,分割一部分intellisense的额外重量可能不值得。@RobertHarvey,没错,但所有扩展方法都会出现在主对象之外,这可能会创建一个很长的选择集来涉过。这会将方法组织成某种主题。这就是重点。虽然我可以看到相似之处,但所述策略背后的目的似乎并不真正符合适配器的定义。根据我对不同模式的理解:适配器为包装对象提供不同的接口,代理为其提供相同的接口,装饰为其提供增强的接口。(事实上,我在Refactoring.Guru找到了这句话,但它符合我的理解)。因此,在我看来,在这3个接口中,装饰器是更好的选择。@jpt好吧,您的
StringManager
为客户端提供了一个与原始
string
接口不同的接口。您不再有
.Length
属性,而是
GetTwiceLength()
method–不同的接口。AFAIU装饰器导出相同的接口,但执行其他操作。考虑一个超级简化的列表,比如一个接口(或者可能是队列),用一个方法<代码>添加(对象)< /代码>。正常的实现只需将对象添加到数据结构中。您现在可以创建一个
ListItemReplicator
decorator,它可以装饰您的
ListLike
接口[cont.][cont.]复制器装饰器的实现可以如下所示:
class Replicator:ListLike{readonly ListLike original;Replicator(ListLike original){this.orial=original;}公共添加(object obj){original.Add(obj);original.Add(obj);}
。它仍然导出相同的接口,但它通过附加功能(例如日志记录、验证等)来“增强”包装对象的功能,。代理模式通常侧重于控制对对象的访问。我认为就我的目的而言,您对StringManager接口的关注太多,而对程序员来说字符串类外观的最终效果关注不够,这正是我感兴趣的地方。我欣赏
public static StringManager Operations(this String value)
{
    return new StringManager(value);
}
new StringManager("your string").CallMethod();