有没有简单的方法来创建一个使用的类 IFormatProvider它写出一个用户友好的文件大小?
public static string GetFileSizeString(string filePath)
{
FileInfo info = new FileInfo(@"c:\windows\notepad.exe");
long size = info.Length;
string sizeString = size.ToString(FileSizeFormatProvider); // This is where the class does its magic...
}
Run Code Online (Sandbox Code Playgroud)
它应该导致字符串格式化为" 2,5 MB "," 3,9 GB "," 670字节 "等等.
我正在寻找在C#应用程序中使用扩展方法而非静态实用程序类的一些优缺点.
例如,扩展方法列中的一个加号是通过类名调用而不是像"StringUtils"那样的方便.但是,它可能会模糊框架内部和非框架之间的界限.
在C#中创建循环链表的最佳方法是什么?我应该从LinkedList <T>集合中派生出来吗?我打算使用这个链接列表创建一个简单的地址簿来存储我的联系人(这将是一本糟糕的地址簿,但我不在乎因为我将是唯一一个使用它的人).我主要只想创建关键链表,以便我可以在其他项目中再次使用它.
如果您认为链接列表不是正确的方法,请告诉我哪种方式会更好.
是的,所以MS引入了C#3.0的扩展方法.基本上,它允许您向现有类添加新方法,而无需从中继承或更改其实现.我的脑海里立刻响起了警钟.
1)您开始为库或标准库类实现自己的扩展方法.现在它不再标准化了.
2)在OOP中,您可以通过继承或组合定义新类型.实际上扩展方法是什么呢?同样,在使用扩展方法时,没有定义明确的关系.
3)扩展方法是否可以在项目之间移植?如果存在两种方法的扩展方法怎么办?
扩展方法也是一大堆蠕虫值得避免的吗?我可以看到它有优点,因为你输入较少,但不知何故它看起来会导致不好的练习.
意见?
在什么情况下(使用场景)你会选择编写扩展而不是对对象进行子类化?
<完全披露:我不是MS员工; 我个人不知道Mitsu Furota; 我知道这里提到的开源Componax库的作者,但我与他没有任何业务往来; 我不是在创建或计划使用扩展创建任何商业产品:总之:这篇文章来自与我试图(不断)意识到"最佳实践"相关的纯粹智力上的好奇心
我发现扩展方法的想法很"酷",显然你可以用它们做"远远"的事情,就像你在Mitsu Furota(MS)博客文章链接文本中的许多例子一样.
一位私人朋友写了开源Componax图书馆链接文本,那里有一些非凡的设施; 但他完全控制着他的小公司,完全控制代码指南,每一行代码都"通过他的手".
虽然这是我的猜测:我认为/猜测其他问题可能会在大中型软件团队的情况下重新使用Extensions.
在链接文本中查看MS的指南,您会发现:
通常,您可能会比实现自己的方法更频繁地调用扩展方法....一般情况下,我们建议您谨慎实施扩展方法,并且仅在必要时实施.必要时,必须扩展现有类型的客户端代码应通过创建从现有类型派生的新类型来实现.有关更多信息,请参见继承(C#编程指南)....当编译器遇到方法调用时,它首先在类型的实例方法中查找匹配项.如果未找到匹配项,它将搜索为该类型定义的任何扩展方法,并绑定到它找到的第一个扩展方法.
在Ms的链接文本中:
扩展方法没有特定的安全漏洞.它们永远不能用于模拟类型上的现有方法,因为所有名称冲突都被解析为有利于类型本身定义的实例或静态方法.扩展方法无法访问扩展类中的任何私有数据.
对我来说显而易见的因素包括:
我假设你不会写一个扩展,除非你期望它被非常普遍地使用.另一方面:难道你不能对子类别说同样的话吗?
知道我们可以将它们编译成一个单独的dll,并添加已编译的dll,并引用它,然后使用扩展:是"酷",但是这"平衡"编译器中固有的成本首先必须检查才能看到如果实例方法如上所述定义.或者,在"名称冲突"的情况下使用静态调用方法来确保调用扩展而不是实例定义的成本?
频繁使用Extensions会影响运行时性能或内存使用:我不知道.
因此,与子分类相比,我会感谢您的想法,或了解您如何/何时做或不做,使用扩展.
比尔,谢谢
我正在寻找一种为任何对象创建通用包装器的方法.
包装器对象的行为就像它包装的类一样,但是可以有更多的属性,变量,方法等,例如对象计数,缓存等.
假设包装类叫做Wrapper,要包装的类叫做Square,并且有构造函数Square(double edge_len)和属性/方法EdgeLength和Area,我想用它如下:
Wrapper<Square> mySquare = new Wrapper<Square>(2.5); /* or */ new Square(2.5);
Console.Write("Edge {0} -> Area {1}", mySquare.EdgeLength, mySquare.Area);
Run Code Online (Sandbox Code Playgroud)
显然我可以为我想要包装的每个类创建一个这样的包装类,但我正在寻找一个通用的解决方案,即Wrapper<T>可以处理原始类型和复合类型(尽管在我目前的情况下,我会很高兴只包装我自己的类).
建议?
谢谢.
可能重复:
您找到了扩展方法的哪些优点?
好吧,首先,我意识到这听起来有争议,但我并不是说是对抗性的.出于好奇心(或许拼图是一个更好的词),我问一个严肃的问题.
为什么扩展方法引入.NET?它们提供了什么好处,除了让事情看起来很好(并且"好",我的意思是"看似像实例方法")?
对我来说,使用像这样的扩展方法的任何代码:
Thing initial = GetThing();
Thing manipulated = initial.SomeExtensionMethod();
Run Code Online (Sandbox Code Playgroud)
是误导,因为它暗示这SomeExtensionMethod是一个实例成员Thing,误导开发人员相信(至少作为一种直觉......你可能会否认它,但我肯定已经注意到这一点)(1)SomeExtensionMethod可能是有效实施的, (2)因为SomeExtensionMethod实际上它看起来像是课堂的一部分,Thing如果Thing在未来的某个时候进行修改,它肯定会保持有效(只要作者Thing知道他/她在做什么).
但事实是,扩展方法无法访问受保护的成员或他们正在扩展的类的任何内部工作,因此它们与任何其他静态方法一样容易破坏.
我们都知道以上很容易:
Thing initial = GetThing();
Thing manipulated = SomeNonExtensionMethod(initial);
Run Code Online (Sandbox Code Playgroud)
对我来说,这似乎更多,因为缺乏一个更好的词,诚实.
我错过了什么?为什么存在扩展方法?
我有两个C#类,它们具有许多相同的属性(按名称和类型).我希望能够将实例中的所有非空值复制Defect到实例中DefectViewModel.我希望用反射来做,使用GetType().GetProperties().我尝试了以下方法:
var defect = new Defect();
var defectViewModel = new DefectViewModel();
PropertyInfo[] defectProperties = defect.GetType().GetProperties();
IEnumerable<string> viewModelPropertyNames =
defectViewModel.GetType().GetProperties().Select(property => property.Name);
IEnumerable<PropertyInfo> propertiesToCopy =
defectProperties.Where(defectProperty =>
viewModelPropertyNames.Contains(defectProperty.Name)
);
foreach (PropertyInfo defectProperty in propertiesToCopy)
{
var defectValue = defectProperty.GetValue(defect, null) as string;
if (null == defectValue)
{
continue;
}
// "System.Reflection.TargetException: Object does not match target type":
defectProperty.SetValue(viewModel, defectValue, null);
}
Run Code Online (Sandbox Code Playgroud)
最好的方法是什么?我应该维护单独的Defect属性和DefectViewModel属性列表,以便我可以做到viewModelProperty.SetValue(viewModel, defectValue, null)吗?
c# ×7
.net ×2
c#-3.0 ×2
addressbook ×1
filesize ×1
formatting ×1
linked-list ×1
mapping ×1
properties ×1
reflection ×1
wrapper ×1