とか言いつつ今日は暑いです。
えー、8月も間もなく終わり、前回のエントリからほぼ3週間ですか。思いの外サボってしまいました…。
そんな時期もありますよね(白目)。ボチボチいきます…。
とか言いつつ今日は暑いです。
えー、8月も間もなく終わり、前回のエントリからほぼ3週間ですか。思いの外サボってしまいました…。
そんな時期もありますよね(白目)。ボチボチいきます…。
public static void ByCounts(string path, int keepCount)
{
Directory.GetFiles(path)
.OrderByDescending(f => f)
.Skip(keepCount)
.ToList()
.ForEach(f => File.Delete(f));
}
ま、シンプルですよね。public static void BySize(string path, long size)
{
long totalSize = 0;
Directory.GetFiles(path)
.OrderByDescending(f => f)
.SkipWhile(f => (totalSize += new FileInfo(f).Length) < size)
.ToList()
.ForEach(f => File.Delete(f));
}
public static void ByDays(string path, int days, int startPos, string dateForm)
{
var target = DateTime.Today.AddDays(-days);
Directory.GetFiles(path)
.Where(f => DateTime.ParseExact(
Path.GetFileName(f).Substring(startPos, dateForm.Length),
dateForm,
System.Globalization.DateTimeFormatInfo.InvariantInfo) < target)
.ToList()
.ForEach(f => File.Delete(f));
}
DeleteOldLogFiles.ByDays(logFolderPath, 3, 4, "yyyy-MM-dd");
public class Dummy
{
private DataTable table;
public Dummy(DataTable table)
{
this.table = table;
}
public int SumOfQuantity
{
get
{
int sum = 0;
foreach (DataRow row in table.Rows)
{
sum += (int)row["qty"];
}
return sum;
}
}
public int FirstOrder
{
get { return (int)table.Rows[0]["order"]; }
}
public void SetDone()
{
foreach (var row in table.Rows.Cast<DataRow>().Where(r => (int)r["f"] == 0))
{
row["f"] = 1;
row["doneAt"] = DateTime.Now;
}
}
}
>"C:\Program Files\Microsoft Visual Studio 11.0\Team Tools\ Static Analysis Tools\FxCop\FxCopCmd.exe" /f:D:\Projects\Da taTableRuleDummy\bin\Debug\DataTableRuleDummy.dll /c
public class Dummy
{
private DataTable table;
public Dummy(DataTable table)
{
this.table = table;
}
public int SumOfQuantity
{
get { return table.AsEnumerable().Sum(r => r.Field<int>("qty")); }
}
public int FirstOrder
{
get { return table.AsEnumerable().First().Field<int>("order"); }
}
public void SetDone()
{
foreach (var row in table.Select("flag=0"))
{
row.SetField("flag", 1);
row.SetField("doneAt", DateTime.Now);
}
}
}
| イマイチ好みじゃない | ずいぶんマシ |
|---|---|
| foeach構文でDataTable.Rowsプロパティを使う。 | DataTable.AsEnumerable拡張メソッドまたはDataTable.Selectメソッドを使う。 |
| LINQを使うために、DataTable.RowsプロパティにEnumerable.Cast<DataRow>拡張メソッドを使う。 | DataTable.AsEnumerable拡張メソッドまたはDataTable.Selectメソッドを使う。 |
| DataRowCollectionクラスのインデクサを使う。 | DataTable.AsEnumerable拡張メソッドまたはDataTable.Selectメソッドを使う。(インデクサは使わない。) |
| DataRowクラスのインデクサを使う。 | DataRow.Field拡張メソッドとDataRow.SetField拡張メソッドを使う。 |
using Microsoft.FxCop.Sdk;
namespace DataTableRules
{
public abstract class BaseDataTableRule : BaseIntrospectionRule
{
protected BaseDataTableRule(string name) : base(
name, "DataTableRules.CustomRules", typeof(BaseDataTableRule).Assembly) {}
public override ProblemCollection Check(Member member)
{
var m = member as Method;
if (m != null)
Visit(m);
return Problems;
}
}
}
using System;
using Microsoft.FxCop.Sdk;
namespace DataTableRules
{
public class NoUseGetEnumeratorMethodToDataTableRows : BaseDataTableRule
{
public NoUseGetEnumeratorMethodToDataTableRows()
: base("NoUseGetEnumeratorMethodToDataTableRows") {}
public override void VisitMethodCall(MethodCall call)
{
var binding = call.Callee as MemberBinding;
var target = binding.TargetObject;
var member = binding.BoundMember;
if (member.Name.Name == "GetEnumerator" &&
target.Type.FullName == "System.Data.DataRowCollection")
{
Problems.Add(new Problem(GetResolution()));
}
base.VisitMethodCall(call);
}
}
}
using System;
using Microsoft.FxCop.Sdk;
namespace DataTableRules
{
public class NoUseCastMethodToDataTableRows : BaseDataTableRule
{
public NoUseCastMethodToDataTableRows()
: base("NoUseCastMethodToDataTableRows") {}
public override void VisitMethodCall(MethodCall call)
{
var binding = call.Callee as MemberBinding;
var member = binding.BoundMember;
if (member.FullName ==
"System.Linq.Enumerable.Cast<System.Data.DataRow>"
+ "(System.Collections.IEnumerable)")
{
Problems.Add(new Problem(GetResolution()));
}
base.VisitMethodCall(call);
}
}
}
using System;
using Microsoft.FxCop.Sdk;
namespace DataTableRules
{
public class NoUseIndexerToDataTableRows : BaseDataTableRule
{
public NoUseIndexerToDataTableRows()
: base("NoUseIndexerToDataTableRows") {}
public override void VisitMethodCall(MethodCall call)
{
var binding = call.Callee as MemberBinding;
var member = binding.BoundMember;
if (member.FullName.StartsWith(
"System.Data.DataRowCollection.get_Item(", StringComparison.Ordinal))
{
Problems.Add(new Problem(GetResolution()));
}
base.VisitMethodCall(call);
}
}
}
using System;
using Microsoft.FxCop.Sdk;
namespace DataTableRules
{
public class NoUseIndexerToDataRow : BaseDataTableRule
{
public NoUseIndexerToDataRow() : base("NoUseIndexerToDataRow") {}
public override void VisitMethodCall(MethodCall call)
{
var binding = call.Callee as MemberBinding;
var member = binding.BoundMember;
if (member.FullName.StartsWith(
"System.Data.DataRow.get_Item(", StringComparison.Ordinal) ||
member.FullName.StartsWith(
"System.Data.DataRow.set_Item(", StringComparison.Ordinal))
{
Problems.Add(new Problem(GetResolution()));
}
base.VisitMethodCall(call);
}
}
}
<?xml version="1.0" encoding="utf-8" ?>
<Rules FriendlyName="データテーブルの使い方の規則">
<Rule TypeName="NoUseCastMethodToDataTableRows"
Category="My.DataTable" CheckId="DT0001">
<Name>DataTable.RowsにCast<DataRow>()拡張メソッドを使用しません</Name>
<Description>可読性の向上のため、DataTable.RowsにCast<DataRow>拡張メソッド
を使用しません。</Description>
<Url />
<Resolution>DataTable.RowsにCast<DataRow>拡張メソッドが使用されています。
さらなる条件の絞り込みや、ソートが必要であればDataTable.Select()メソッドを、
そうでなければDataTable.AsEnumerable()拡張メソッドを使用してください。
</Resolution>
<Email />
<MessageLevel Certainty="80">Warning</MessageLevel>
<FixCategories>NonBreaking</FixCategories>
<Owner />
</Rule>
<Rule TypeName="NoUseGetEnumeratorMethodToDataTableRows"
Category="My.DataTable" CheckId="DT0002">
<Name>foreach構文でDataTable.Rowsを使用した列挙を行いません</Name>
<Description>LINQとの親和性向上のため、DataTable.Rows.GetEnumerable()メソッドを
使用しません。</Description>
<Url />
<Resolution>DataTable.Rows.GetEnumerable()が使用されています。さらなる条件の
絞り込みや、ソートが必要であればDataTable.Select()メソッドを、そうでなければ
DataTable.AsEnumerable()拡張メソッドを使用してください。</Resolution>
<Email />
<MessageLevel Certainty="80">Warning</MessageLevel>
<FixCategories>NonBreaking</FixCategories>
<Owner />
</Rule>
<Rule TypeName="NoUseIndexerToDataTableRows"
Category="My.DataTable" CheckId="DT0003">
<Name>DataTable.Rowsのインデクサを使用しません</Name>
<Description>可読性の向上のため、DataTable.Rowsのインデクサを使用しません。
</Description>
<Url />
<Resolution>DataTable.Rowsのインデクサが使用されています。テーブル内の各行を列挙
する場合には、DataTable.Select()メソッド、またはDataTable.AsEnumerable()拡張
メソッドを使用してforeach構文で列挙してください。 先頭行のみ取り出す場合には、
DataTable.AsEnumerable()拡張メソッドと、Enumerable.First()を使用して一時変数に
代入後、使用してください。
例:var firstRow = dt.AsEnumerable().First();</Resolution>
<Email />
<MessageLevel Certainty="80">Warning</MessageLevel>
<FixCategories>NonBreaking</FixCategories>
<Owner />
</Rule>
<Rule TypeName="NoUseIndexerToDataRow"
Category="My.DataTable" CheckId="DT0004">
<Name>DataRowのインデクサを使用しません</Name>
<Description>可読性の向上のため、DataRowのインデクサを使用しません。
</Description>
<Url />
<Resolution>DataRowのインデクサが使用されています。テーブル内の各行のカラムに値
を設定、または取得する場合は、DataRow.SetField<T>()拡張メソッド、および
DataRow.Field<T>()拡張メソッドを使用してください。</Resolution>
<Email />
<MessageLevel Certainty="80">Warning</MessageLevel>
<FixCategories>NonBreaking</FixCategories>
<Owner />
</Rule>
</Rules>