2018年10月16日

MvcSiteMapProvider PreservedRouteParameters於麵包屑的使用

在使用 MvcSiteMapProvider套件產生麵包屑時,如果使用 PreservedRouteParameters增加參數,則在子節點的 url中需要附帶相同的參數,麵包屑中父節點的 url才會帶入。 '

舉例,現在有一個父節點 /Order/List?groupId=1,一個子節點 /Order/Detail?orderId=3,程式需要這樣寫:

DynamicNodeProvider:
DynamicNode parentNode = new DynamicNode
{
    Title = "訂單列表",
    Key = "NodeA",
    Controller = "Order",
    Action = "List"
};

parentNode.PreservedRouteParameters.Add("groupId");

DynamicNode childNode = new DynamicNode
{
    Title = "訂單明細",
    ParentKey = "NodeA"
    Key = "NodeB",
    Controller = "Order",
    Action = "Detail"
};

OrderController:
public class OrderController : Controller
{
    public ActionResult List(int groupId)
    {
        ...
    }

    public ActionResult List(int orderId, int groupId)
    {
        ...
    }
}

Order List HTML:
<a href="/Order/Detail?orderId=3&groupId=1" ></a>

2018年3月22日

C# lock (typeof (Object)) CA2002

在 IBatisNet內看到這樣的用法:
lock (typeof (SqlMapper))
{
  ...
}

程式碼分析給出了 CA2002
不知道為什麼會寫出 lock typeof object的東西,這樣真的能鎖住東西?

C# 巢狀 Using 的程式碼分析警告 CA2202

使用 Visual Studio的程式碼分析(Code Analysis)功能,如果程式碼中有使用巢狀 using時:
using (StreamReader sr = new StreamReader(inputStream))
{
  using (CsvReader csvReader = new CsvReader(sr))
  {
    ..
  }
}
就會出現警告 CA2202:不要多次處置物件的 Dispose方法

但是在 MSDN的這篇 IDisposable.Dispose Method ()說明中寫道:如果一個物件被多次呼叫 Dispose方法,第一次之後的呼叫都會被忽略

 If an object's Dispose method is called more than once, the object must ignore all calls after the first one. The object must not throw an exception if its Dispose method is called multiple times. Instance methods other than Dispose can throw an ObjectDisposedException when resources are already disposed.

所以實際使用上是沒問題的
但是這樣在 Code Analysis就會卡著一個甚至多個警告訊息,看了很礙眼
那就在 function上加一個 SuppressMessage,讓這個警告不會再出現
[SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")]
public byte[] FunctionName(...) {

好啦這是在 StackOverflow上挖出來的解法
但是討論串內要直接用 SuppressMessage,還是用醜一點的寫法解掉這個訊息,還是有很多爭論

2018年1月10日

[JS] 字串轉數字使用 *1比 parseInt快

先驗證 parseInt和 *1轉化後的結果是否相同:
var strNum = "10000"
var parseNum = parseInt(strNum)
var multiplyNum = strNum * 1
typeof strNum
// "string"
typeof parseNum
// "number"
typeof multiplyNum
// "number"
parseNum
// 10000
multiplyNum
// 10000

接著比較兩種方式的效能
function testA(time, str) {
    for (i=0;i<time;++i) {
        var tmp = parseInt(str);
    }
}
function testB(time, str) {
    for (i=0;i<time;++i) {
        var tmp = str * 1;
    }
}

console.time('testA');
testA(10000000, "12345678");
console.timeEnd('testA');
// testA: 1226.073974609375ms

console.time('testB');
testB(10000000, "12345678");
console.timeEnd('testB');
// testB: 622.14208984375ms

console.time('testA');
testA(10000000, "82736491");
console.timeEnd('testA');
// testA: 1202.213134765625ms

console.time('testB');
testB(10000000, "82736491");
console.timeEnd('testB');
// testB: 619.800048828125ms

console.time('testA');
testA(10000000, "1");
console.timeEnd('testA');
// testA: 95.97900390625ms

console.time('testB');
testB(10000000, "1");
console.timeEnd('testB');
// testB: 67.47216796875ms

console.time('testA');
testA(10000000, "");
console.timeEnd('testA');
// testA: 719.873779296875ms

console.time('testB');
testB(10000000, "");
console.timeEnd('testB');
// testB: 235.06103515625ms

console.time('testA');
testA(10000000, "0");
console.timeEnd('testA');
// testA: 92.878173828125ms

console.time('testB');
testB(10000000, "0");
console.timeEnd('testB');
// testB: 74.76416015625ms