2017年9月26日 星期二

Func 委派的用法

Func 委派的用法

https://dotblogs.com.tw/brooke/2014/08/02/146142

摘要:Func 委派的用法
一、
1.委派的範例為
using System;

//宣告一個委派型別為ConvertMethod,
//並規範入為string型別,輸出為string型別
delegate string ConvertMethod(string inString);

public class DelegateExample
{
   public static void Main()
   {
      // Instantiate delegate to reference UppercaseString method
      // 將委派型別ConvertMethod的實體去參考UppercaseString方法
      ConvertMethod aConvertMeth = UppercaseString;
      string name = "Dakota";
      // Use delegate instance to call UppercaseString method
      Console.WriteLine(aConvertMeth(name));
   }

   private static string UppercaseString(string inputString)
   {
      return inputString.ToUpper();
   }
}

2.不用明確定義委派方法,以Func來簡化程式碼為
using System;

public class GenericFunc
{
    public static void Main()
    {
        // Instantiate delegate to reference UppercaseString method
        //Func<in T, out TResult>
        Func<string, string> aConvertMethod = UppercaseString;
        string name = "Dakota";
        // Use delegate instance to call UppercaseString method
        Console.WriteLine(aConvertMethod(name));
        Console.ReadKey();
    }

    private static string UppercaseString(string inputString)
    {
        return inputString.ToUpper();
    }
}

3.使用匿名方法
using System;

public class Anonymous
{
   public static void Main()
   {
      Func<string, string> convert = delegate(string s){ return s.ToUpper();}; 

      string name = "Dakota";
      Console.WriteLine(convert(name));   
   }
}

4.使用Lambda運算式
using System;

public class Anonymous
{
   public static void Main()
   {
      Func<string, string> convert = s => s.ToUpper(); 

      string name = "Dakota";
      Console.WriteLine(convert(name));   
   }
}

二、
若要參考有一個參數並傳回 void (在 Visual Basic 中是宣告為 Sub 而非 Function) 的方法,
可使用泛型 Action<T> 委派代替。
using System;

public class GenericFunc
{
    public static void Main()
    {

        Action<string> aConvertMethod = UppercaseString;
        string name = "Dakota";

        aConvertMethod(name);
        Console.ReadKey();
    }

    private static void UppercaseString(string inputString)
    {
        Console.WriteLine(inputString.ToUpper());
    }
}

三、
Action<T>泛型的委派型別,也是跟Func一樣,只是回傳值為void。
每個Func委派型別的簽章,傳入的參數會是零到四,而最後一個的型別參數是代表回傳型別。
例如:Func<string,int>,代表傳入型別為string而回型別為int。

2017年9月25日 星期一

Visual Studio 2012 無法啟動IIS Express Web 伺服器

Visual Studio 2012 無法啟動IIS Express Web 伺服器

http://marco.easyusing.com/2012/12/visual-studio-2012-iis-express-web.html

字串_Replace用法

String s = "文字1 - Microsoft word";

//先將空格轉為$,再將"-"刪
s = s.Replace(" ", "$").Replace("-", "");
 
結果
文字1$$Microsoft$word



C#中的IntPtr類型

https://read01.com/zh-tw/DAOJK.html#.WcjooMgjFPY

C#中的IntPtr類型

問:
c#中無法將類型「int」隱式轉換為「System.IntPtr」
這個是我引用了一個api函數時出現的問題,我在聲明中把intptr換成了int還是不可以,這是為什麼呢?要如何處理呢?

答:
您好,C#中的IntPtr類型稱為「平台特定的整數類型」,它們用於本機資源,如窗口句柄。
資源的大小取決於使用的硬體和作業系統,但其大小總是足以包含系統的指針(因此也可以包含資源的名稱)。

所以,在您調用的API函數中一定有類似窗體句柄這樣的參數,那麼當您聲明這個函數時,您應該將它顯式地聲明為IntPtr類型。

例如,在一個C#程序中調用Win32API mciSendString函數控制光碟驅動器,這個函數的函數原型是:

MCIERROR mciSendString
(
LPCTSTR lpszCommand,
LPTSTR lpszReturnString,
UINT cchReturn,
HANDLE hwndCallback
);

首先在C#中聲明這個函數:

[DllImport("winmm.dll")]

private static extern long mciSendString(string a,string b,uint c,IntPtr d);

然後用這樣的方法調用:

mciSendString("set cdaudio door open", null, 0, this.Handle);

您也可以使用IntPtr.Zero將句柄設置為0;

或者使用類型強制轉換:

mciSendString("set cdaudio door open", null, 0, (IntPtr)0 );

或者,使用IntPtr構造函數:

IntPtr a = new IntPtr(2121);

這裡有兩點比較重要:

一是在C#中聲明Win32API時,一定要按照WinAPI的原型來聲明,不要改變它的數據類型;

二是儘量不要過多使用類型強制轉換或構造函數的方式初始化一個IntPtr類型的變量,這樣會使程序變得難於理解並容易出錯。

希望這些信息對您有幫助。



2017年9月24日 星期日

如何使用 CAST 與 CONVERT 格式化日期與時間資料

如何使用 CAST 與 CONVERT 格式化日期與時間資料


http://ithelp.ithome.com.tw/articles/10008820


SSMS--T-SQL偵錯工具教學


http://blog.kkbruce.net/2011/01/ssms-t-sql.html#.WcdyAMgjFPY

2017年9月15日 星期五

asp.net-ExecuteNonQuery-的回傳值

ExecuteNonQuery 方法不會返回任何資料庫的資料, 它只會返回整數值來表示成功或受影響的資料列數目.


  • create

If use ExecuteNonQuery to create or modify database structure, eg. create table, this method returns -1 if success, returns 0 if fail.

ExecuteNonQuery 用來創建或修改資料庫的結構,如建立table,成功回1,失敗回0


  •  INSERT, UPDATE, DELETE

If use ExecuteNonQuery to INSERT, UPDATE, DELETE, this method returns the Number of affected data row, but if fail, it returns 0.

如果用來新增修改刪除,成功它會返回受影響的列數,失敗回0.

[ADO.NET] 為何 / 如何 使用 SQLParameter 物件

[ADO.NET] 為何 / 如何 使用 SQLParameter 物件


在上一個範例 [ADO.NET] 如何 使用 SQLCommand 查詢資料庫https://dotblogs.com.tw/yc421206/archive/2009/06/10/8776.aspx
當中
1.在插入資料的SQL陳述句,若能使用 Parameter 將會提高安全性,若使用者輸入了特別符號,也比較不會出問題;而寫ASP.NET必須更注意安全性的問題。
2.Parameter 可以 (1)檢查參數的型別 (2)檢查資料長度 (3)確保參數為非可執行的SQL命令 ,如下圖。
3.上一個範例的queryString 變數是
queryString = "insert into mytable (myregion,myname) values(N' " + region + "',N'" + name + "' )";


改為以下
string queryString = "insert into mytable (myregion,myname) values(@myregion,@myname)";


主要是使用"@參數名稱",來代替原本的變數。


4.使用 SQLCommand.Parameters 屬性是引用了 SqlParameterCollection 類別,所以也是集合的一種,如果忘了集合是啥米小請看 [C#.NET][VB.NET] 一般 / 泛型 Generic Collection 集合型別介紹https://dotblogs.com.tw/yc421206/archive/2009/01/25/6941.aspx


5.Parameter 用法很簡單,如下範例:"@myregion", 為變數、textBox1.Text 為對應變數的數值
cmd.Parameters.AddWithValue("@myregion", textBox1.Text);


如何使用SQLParameter 物件


以下範例需引用 System.Data.SqlClient 命名空間,以下為部份範例


1.引用SqlConnection物件連接資料庫
using (SqlConnection cn = new SqlConnection(cs))


2.開啟資料庫
cn.Open();


3.引用SqlCommand物件
using (SqlCommand cmd = new SqlCommand(queryString, cn))


4.加入 SQLParameters(以下執行結果均為相同)


  4.1 使用 SQLCommand.Parameters.Add 方法
      cmd.Parameters.Add("@myregion", SqlDbType.NVarChar);
      cmd.Parameters["@myregion"].Value = textBox1.Text;


  4.2 使用 SQLCommand.Parameters.AddWithValue 方法
     cmd.Parameters.AddWithValue("@myregion", textBox1.Text);


    
  4.3 使用 SQLCommand.Parameters.Add 方法加入 SQLParameters 類別
     cmd.Parameters.Add(new SqlParameter("@myregion", textBox1.Text));


5.執行SQL語法
cmd.ExecuteNonQuery();



2017年9月14日 星期四

2017年9月13日 星期三

錯誤 HRESULT E_FAIL 已經從呼叫傳回至 COM 元件

FAQ-TFS-錯誤 HRESULT E_FAIL 已經從呼叫傳回至 COM 元件。 (類型 COMException)
http://blog.xuite.net/liangcw/IT/503241520

https://dotblogs.com.tw/justingong/2011/06/13/28198

2017年9月12日 星期二

sqlite檔案加密不能用工具直接開啟

  1. sqlite檔案加密不能用工具直接開啟需用程式解密後開啟
  2. sqlite.interop.dll' 找不到指定的模組問題
  1. 先加入參考後
  1. 複製檔案到相對應的位置
  • 帶bundle的表示動態庫是按混合模式編譯的,在使用的時候只需要System.Data.SQLite.dll就可以了,而不帶bundle的則是將非託管部分和託管部分分別編譯,System.Data.SQLite.dll不能獨立使用,還需要有SQLite.Interop.dll才能使用。我用的是不帶bundle包中的System.Data.SQLite.dll,解決方法是要麼手工複製SQLite.Interop.dll和exe放一塊(不能用引用),要麼換成引用bundle包中的System.Data.SQLite.dll。

更換圖示_[C#]使用SharpShell實現Shell Icon Overlay功能

[C#]使用SharpShell實現Shell Icon Overlay功能


https://dotblogs.com.tw/larrynung/2013/02/18/91037

https://www.codeproject.com/Articles/522665/NET-Shell-Extensions-Shell-Icon-Handlers

ip.IPv4Mask.GetHashCode()


if (ip.IPv4Mask != null && ip.IPv4Mask.GetHashCode() == 0)
                        {
                            ethernetIPv6 = ip.Address.ToString();
                            //測試用
                            hashcode += ip.IPv4Mask.GetHashCode();
                            continue;
                        }


IPv4Mask: 0.0.0.0他的GetHashCode() == 0

[C#] 條件式中常用的&和&& |和||的差異

取自
http://charleslin74.pixnet.net/blog/post/454321301-%5bc%23%5d-%E6%A2%9D%E4%BB%B6%E5%BC%8F%E4%B8%AD%E5%B8%B8%E7%94%A8%E7%9A%84%26%E5%92%8C%26%26-%7c%E5%92%8C%7c%7c%E7%9A%84%E5%B7%AE%E7%95%B0

C#中條件式我們常用&或&&來確認條件是否全部符合規範,而用|或||來確認條件是否部分符合規範
那為什麼又要有&和&&呢?我們用例子來說明
int myAge = 12;
string bloodType = "O";
if(myAge == 12 & bloodType == "O")
{
    Console.WriteLine("do something");
}
上面的例子只有一個&,所以會先檢查myAge是不是等於12,再檢查bloodType是不是等於O.
那今天我們改一下例子
int myAge = 13;
string bloodType = "O";
if(myAge == 12 & bloodType == "O")
{
    Console.WriteLine("do something");
}
它一樣會先檢查myAge是不是等於12,再檢查bloodType是不是等於O.
但這時你會有個疑問,&不是二個條件式都要為真時才符合嗎,那第一個myAge就不符合了,何必浪費時間去檢查第二個條件呢??
所以才會有&&的出現定
int myAge = 13;
string bloodType = "O";
if(myAge == 12 && bloodType == "O")
{
    Console.WriteLine("do something");
}
改成用&&後,當確認myAge=12時,發現條件不合,就直接跳開了,不會去檢查 bloodType == "O"
這樣程式執行就比較有效率,所以要注意的是,我們通常會把常變動或者重要的條件擺在比較的第一個.
而|和||的差異,其實就&和&&是相同的
int myAge = 13;
string bloodType = "A";
if(myAge == 13 || bloodType == "O")
{
    Console.WriteLine("do something");
}
| 及||是二者中有一為真就符合條件,像上例我們使用||就表示會先檢查myAge == 13
這樣就馬上符合條件了,所以它就不會去檢查bloodType == "O",而是直接執行後續的處理了.
所以 | 是將所有條件都比對後才決定怎麼做,而 || 是只要符合的條件就直接做,後續的條件就不比對了.
是比較有效率的.

2017年9月10日 星期日

[C#] 檔案讀寫

[C#] 檔案讀寫

檔案讀寫是程式設計師很常遇到的問題,在 C# 中與 Java 相同,不管是檔案讀寫、網路資料傳送、螢幕鍵盤輸出入都是以「串流(Stream)」的方式來達成。FileStream、MemoryStream、NetworkStream、GZipStream 等都繼承自 Stream 類別。在這個章節裡我們直接以範例來學習。
一、文字讀寫
1. 將文字寫入 C:\secret_plan.txt 中。
1// 建立檔案串流(@ 可取消跳脫字元 escape sequence)
2StreamWriter sw = new StreamWriter(@"C:\secret_plan.txt");
3sw.WriteLine("write something");            // 寫入文字
4sw.Close();                     // 關閉串流
2. 讀取文字
1// 建立檔案串流(@ 可取消跳脫字元 escape sequence)
2StreamReader sr = new StreamReader(@"C:\secret_plan.txt");
3while (!sr.EndOfStream) {               // 每次讀取一行,直到檔尾
4    string line = sr.ReadLine();            // 讀取文字到 line 變數
5}
6sr.Close();                     // 關閉串流
Stream 類別實作了 IDisposable 介面!它具有 Dispose 方法,你可以呼叫 Dispose 關閉串流或者使用 using statement。
1using (StreamWriter sw = newStreamWriter(@"C:\secret_plan.txt")) {
2    ...
3}
  看到這裡是不是覺得太簡單了呢!等等呢,Visual C# 有一個 OpenFileDialog 的對話框可以用來選取檔案。下面就來看看怎麼使用吧!
Step1:將 OpenFileDialog 控制項拖曳到表單上
拖曳新增後 OpenFileDialog 控制項會出現在 Form Design 下方。在此我們假定該控制項命名 openFileDialog1 。
Step2:撰寫控制碼
在 Form 底下撰寫 OpenFileDialog 的控制碼。
1openFileDialog1.InitialDirectory = @"c:\MyFolder\Default\"// 檔案對話方框開啟的預設資料夾
2// 設定可以選擇的檔案類型
3openFileDialog1.Filter = "Text Files (*.txt)|*.txt|Comma-Delimited Files (*.csv)|*.csv|All Files (*.*)|*.*";
4openFIleDialog1.CheckFileExists = true;             // 若檔案/路徑 不存在是否顯示錯誤訊息
5openFIleDialog1.CheckPathExists = false;
6DialogResult result = openFileDialog1.ShowDialog();     // 顯示檔案對話方框並回傳狀態(DialogResult.OK、DialogResult.Cancel)
7if (result == DialogResult.OK) {
8    // 操作檔案 openFileDialog1.FileName
9}
除了 OpenFileDialog 外,SaveFileDialog 的作法也是一樣的。
二、File 類別 - 更快的方法來處理簡單的檔案管理
1bool b = File.Exists(file_name);        // 判定檔案是否存在
2File.Create(file_name);             // 建立檔案
3string text = File.ReadAllText(file_name);  // 讀取檔案內所有文字
4File.WriteAllText(file_name, text);     // 將 text 寫入檔案
* File 類別還有很多方法,詳細參考 Head First C#、其他書籍或 MSDN
三、物件序列化(serialization)
  物件序列化是一個快速又方便的物件狀態永久保存法,它將物件的狀態(所有成員變數)儲存到檔案中。以下範例展示序列化(serialize)與反序列化(deserialize)。
1[Serializable]              // *這一行很重要
2class AnotherObj {}
3class SomeObj {
4    public int x;           // 該變數會被保存
5    public AnotherObj another;  // 該物件也會被保存,但其類別需加上 [Serializable] 屬性(attribute)
6}
Step1:引入 namespace
在 .cs 檔前頭加上 using System.Runtime.Serialization.Formatters.Binary;
Step2:建立序列化的串流
1BinaryFormatter formatter = new BinaryFormatter();
Step3:開始序列化(serialize)
1Stream output = File.Create(file_name);
2formatter.Serialize(output, objectToSerialize);
3output.Close();
Step4:反序列化(deserialize)
1Stream input = File.OpenRead(file_name);
2SomeObj obj = (SomeObj)formatter.Deserialize(input);
3input.Close();
四、二進制檔案讀寫
  除了文字檔,我們也可能保存 int、float 等變數的數值或是 byte 資料,這時候使用二進制檔案(binary)就比較方便了。
1int value = 43;
2using (FileStream output = File.Create("binarydata.dat")) {         // 寫入整數值
3    BinaryWriter writer = new BinaryWriter(output);
4    writer.Write(value);
5}
6using (FileStream input = new FileStream(@"binarydata.dat", FileMode.Open)) {   // 讀取整數值
7    BinaryReader reader = new BinaryReader(input);
8    int data = reader.ReadInt16();
9}
  以上只針對最簡單的檔案讀寫來說明,其實不僅是檔案,包括網路串流、壓縮串流都是以類似的作法做輸出入,如欲深入瞭解請參閱其他書籍或 MSDN。                          by autosun