joh*_*ose 14 c# extension-methods poco static-classes instance-methods
我对使用方法与C#中的对象进行交互的不同方式有点困惑,特别是以下主要设计差异和后果:
例:
public class MyPoint
{
public double x { get; set; }
public double y { get; set; }
public double? DistanceFrom(MyPoint p)
{
if (p != null)
{
return Math.Sqrt(Math.Pow(this.x - p.x, 2) + Math.Pow(this.y - p.y, 2));
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
如果您只需将方法放在类定义中就可以完成所需的结果,那么为什么POCO与静态辅助类或扩展方法结合起来会更好?
Col*_*lin 16
你问,"如果你只需要在类定义中放置一个方法就可以达到预期的结果,那么为什么POCO与静态辅助类或扩展方法结合起来会更好?"
答案是,这取决于具体情况,以及所讨论的方法是否与您班级的主要关注点直接相关(参见单一责任原则).
下面是一些示例,说明使用每种方法/方法(使用代码示例作为起点)可能是个好主意.
1.实例方法
//This all makes sense as instance methods because you're
//encapsulating logic MyPoint is concerned with.
public class MyPoint
{
public double x { get; set; }
public double y { get; set; }
public double? DistanceFrom(MyPoint p)
{
if (p != null)
return Math.Sqrt(Math.Pow(this.x - p.x, 2) + Math.Pow(this.y - p.y, 2));
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
2.静态类方法 - 错误记录示例.
//Your class doesn't directly concern itself with logging implmentation;
//that's something that is better left to a separate class, perhaps
//a "Logger" utility class with static methods that are available to your class.
public double? DistanceFrom(MyPoint p)
{
try
{
if (p != null)
return Math.Sqrt(Math.Pow(this.x - p.x, 2) + Math.Pow(this.y - p.y, 2));
return null;
}
catch(Exception ex)
{
//**** Static helper class that can be called from other classes ****
Logger.LogError(ex);
//NOTE: Logger might encapsulate other logging methods like...
//Logger.LogInformation(string s)
//...so an extension method would be less natural, since Logger
//doesn't relate to a specific base type that you can create an
//extension method for.
}
}
Run Code Online (Sandbox Code Playgroud)
3.扩展方法 - XML序列化示例.
//Maybe you want to make it so that any object can XML serialize itself
//using an easy-to-use, shared syntax.
//Your MyPoint class isn't directly concerned about XML serialization,
//so it doesn't make sense to implement this as an instance method but
//MyPoint can pick up this capability from this extension method.
public static class XmlSerialization
{
public static string ToXml(this object valueToSerialize)
{
var serializer = new XmlSerializer(valueToSerialize.GetType());
var sb = new StringBuilder();
using (var writer = new StringWriter(sb))
serializer.Serialize(writer, valueToSerialize);
return sb.ToString();
}
}
//example usage
var point = new MyPoint();
var pointXml = point.ToXml(); //<- from the extension method
Run Code Online (Sandbox Code Playgroud)
经验法则是:
410*_*one 12
可访问成员:public,, (如果继承protected,private则无法访问)
定义:相同的类/结构/接口(可以使用partial关键字拆分文件)
被称为:object.Method()
在这种情况下,我的意思是静态方法是在它们操作的类中定义的方法.也就是说,它们与其他类对象一起定义.(MyPoint示例代码中类中定义的静态方法.)
我们都知道(或应该知道)这些是什么以及对他们有什么好处,除了说:
实例方法可以访问所有的 private,protected以及public类的成员.因为这样做static的方法.
在大多数情况下,如果要添加大量方法和/或属性,或者它们会显着更改对象的操作,则应继承原始对象(如果可能).这使您可以访问所有public和protected成员class/struct/interface.
无障碍会员:public
定义:任何类/命名空间
被称为:HelperClass.Method(object)
通过静态助手类方法我暗示static本节引用的方法的实际定义不在实际的类定义范围内.(即类似MyPointHelpers或类似的类,使用您的代码示例.)
Static Helper类方法只能访问public对象的成员(很像Extension方法,我在扩展方法部分之后写了这个部分).
静态助手类和扩展方法密切相关,并且在许多情况下是相同的.因此,我将在"扩展方法"部分中将这些好处留给他们.
无障碍会员:public
定义:任何类/命名空间
被称为:object.Method()
扩展方法只能访问public对象的成员.虽然他们似乎是班上的成员,但事实并非如此.这限制了它们的用途.(需要访问方法的任何的的private或protected成员应该不是一个延伸.)
在我看来,扩展方法有三个巨大的好处.
假设您正在开发类A,并且类中A有大约7种方法.你也知道你想要开发一些你并不总是需要的方法,但如果你做的话,这将是很方便的.您可以使用扩展方法.这些方法将在另一个类中被抽象出来,如果你需要它们,你可以包含(通过类,感谢C#6.0).您知道以后想要使用的罕见方法,但是您知道并不总是需要.
假设您正在开发程序A,并且您正在使用DLL中的类Something.Other.C,您不拥有源代码.现在,您希望添加一个与类交互的方法,Something.Other.C这种方法对于实例或常规静态方法是有意义的,但是您没有源,所以您不能!输入扩展方法,在这里你可以定义一个方法似乎是类的成员Something.Other.C,但实际上的一部分你的代码.
假设您开发自己的库,并将其与许多自己的应用程序一起使用,并且您在开发应用程序时X意识到您可以Y在课堂上A再次使用方法.好了,而不是修改类的定义A(因为这是更大量的工作,你不使用方法Y在任何地方,除了应用程序X),你可以定义一个扩展方法Y,对类A是只有在应用程序存在X.现在,您的方法开销严格限制在应用程序中X.应用程序Z不需要具有此扩展方法.
就性能而言,这取决于方法,他们做什么以及他们如何做.您将受到public正在改变的对象上的任何属性/方法/字段的影响,并且需要衡量其性能.(如果调用public Value而不是private value导致一些重要的验证开销,则实例方法更有意义,因为它可以使用private字段或属性.)
简而言之:
cat.Color = Color.Blue;cat.Meow();File.Open(String, FileMode)是一个返回a的静态方法FileStream.这里不需要有文件的实例.DateTime该类编写扩展方法并不罕见.| 归档时间: |
|
| 查看次数: |
7314 次 |
| 最近记录: |