C# 笔记

1、枚举的转换

public enum GnssMessageType { Unknown = -1, GPGGA = 218, GPRMC = 225 }
string typeName = "GPGGA";
GnssMessageType type;
//尝试转换为枚举,假如转换失败,标记为未知类型
Enum.TryParse(typeName, out type);
if (!Enum.IsDefined(typeof(GnssMessageType), type))
    type = GnssMessageType.Unknown;

2、C#判断对象类型

Student student_jack = new Student("Jack");
bool is_jack_student = student_jack is Student;

3、用反射动态绑定控件事件

容器窗体内包括一个1列2行的TableLayoutPanel控件,第1行为若干按钮,第2行等待填充其它控件;重载构造器并添加绑定事件方法


C# 笔记_第1张图片
容器窗体
        /// 
        /// 容器窗体初始化,指定要填充的子控件以及停靠方式
        /// 
        /// 待填充进来的子控件
        /// 停靠方式,为空则按默认方式停靠
        public FormContainer(Control child, DockStyle? dockStyle)
        {
            InitializeComponent();
            if (child == null)
                return;
            //假如为Windows窗体,则取消顶级窗口属性
            if (child is Form)
                ((Form)child).TopLevel = false;
            this.tableLayoutPanel_Main.Controls.Add(child, 0, 1); //在TableLayoutControl第1列第2行添加
            this.Name = child.Name; //改变容器类名称
            this.AddClickEvents(this, child); //绑定点击方法
            if (dockStyle != null)
                child.Dock = dockStyle.Value;
        }

        /// 
        /// 将指定控件的子控件Click委托绑定其它控件中的Click方法,假如有子控件则在子控件中查找
        /// 
        /// 在其下子控件中寻找Click委托的控件
        /// 在其中寻找绑定方法的控件
        private void AddClickEvents(Control body, Control child)
        {
            //循环子控件,,否则
            foreach (Control control in body.Controls)
            {
                //假如子控件亦有子控件则递归
                if (control.HasChildren)
                {
                    this.AddClickEvents(control, child);
                    continue;
                }
                //假如为按钮且可见则绑定Click方法,方法名称为[按钮名称_Click],区分大小写
                else if (control is Button/* && control.Visible*/)
                {
                    EventInfo click = control.GetType().GetEvent("Click"); //按名称寻找事件
                    MethodInfo method = child.GetType().GetMethod(string.Format("{0}_Click", control.Name), new Type[] { typeof(object), typeof(EventArgs) }); //按名称与参数寻找方法
                    if (method == null)
                        continue;
                    Delegate handler = Delegate.CreateDelegate(click.EventHandlerType, child, method); //TODO 第二个参数需为方法所在的控件
                    click.AddEventHandler(control, handler);
                }
            }
        }

新建用户控件并添加名称符合规则的Click方法


C# 笔记_第2张图片
用户控件
        /// 
        /// 新增方法
        /// 
        /// 
        /// 
        public void Button_Add_Click(object sender, EventArgs e)
        {
            object obj = this;
            this.label1.Text = "444";
            this.label3.Text = "666";
        }

调用方法

            FormContainer container = new FormContainer(new UserControlExample(), DockStyle.Fill);
            this.ShowForm(container);

结果


C# 笔记_第3张图片
调用结果

4、使用LAMBDA表达式(LINQ)时同时给出索引

string[] names = new string[] { "Jack", "Jameson", "Laura" };
List list = 
names.Select((name, index) => new { name, index })
     .Where(a => a.name.StartsWith("L") || a.index == 0).ToList();

5、C#粘贴板

1)复制到粘贴板

Clipboard.SetDataObject(this.textBox_Info.Text);
Clipboard.SetText(this.textBox_Info.Text);
this.label_Copied.Visible = true;
new Thread(new ThreadStart(() =>
{
    Thread.Sleep(1500);
    this.label_Copied.SafeInvoke(() =>
    {
        this.label_Copied.Visible = false;
    });
}))
{ IsBackground = true }.Start();

2)从粘贴板粘贴

// Declares an IDataObject to hold the data returned from the clipboard.
// Retrieves the data from the clipboard.
IDataObject iData = Clipboard.GetDataObject();

// Determines whether the data is in a format you can use.
if(iData.GetDataPresent(DataFormats.Text))
{
    // Yes it is, so display it in a text box.
    textBox2.Text = (String)iData.GetData(DataFormats.Text); 
}

6、protobuf-net的应用问题

0) NUGET安装

VS内进入程序包管理器控制台输入

PM> Install-Package protobuf-net

卸载则输入以下命令

PM> Uninstall-Package protobuf-net

1) ProtoMember序号问题

不大于536870911,且应避开范围19000-19999
Notes for Identifiers

they must be positive integers (for best portability, they should be <= 536870911 and not in the range 19000-19999)

2) 构造器

假如在反序列化过程中存在有参构造器,则无参构造器亦必须同时存在

    [ProtoContract]
    public class SomeObject
    {
        [ProtoMember(1)]
        public int Index { get; set; }

        [ProtoMember(2)]
        public DateTime Time { get; set; }

        /// 
        /// 无参构造器,在反序列化过程中假如存在有参构造器,则亦必须同时存在
        /// 
        public SomeObject() { }

        public SomeObject(int index, DateTime time)
        {
            this.Index = index;
            this.Time = time;
        }
    }

3) 字段支持

假如引用类型字段要序列化,则该类型在定义时必须支持序列化,否则不需要

    [ProtoContract]
    public class OtherObject
    {
        [ProtoMember(1)]
        public string Message { get; set; }
    }

    [ProtoContract]
    public class SomeType
    {
        [ProtoMember(1)]
        public int Id { get; set; }

        [ProtoMember(2)]
        public string Name { get; set; }

        [ProtoMember(3)]
        public List Values { get; set; }

        /// 
        /// Object属性,假如引用类型字段要序列化,则该类型在定义时必须支持序列化,否则不需要
        /// 
        [ProtoMember(4)]
        public SomeObject Object { get; set; }

        /// 
        /// OtherObject属性,假如引用类型字段要序列化,则该类型在定义时必须支持序列化,否则不需要
        /// 
        [ProtoMember(5)]
        public OtherObject OtherObject { get; set; }

        public override string ToString()
        {
            return string.Format("{0}: {1}", this.Id, this.Name);
        }
    }

4) 继承

继承关系必须显性地声明,且在同一个类的范围内ProtoInclude与ProtoMember的序号不可重复

    [ProtoContract]
    [ProtoInclude(1, typeof(SomeDerivedType))]
    public class SomeBaseType
    {
        [ProtoMember(2)]
        public int Id { get; set; }
    }

    [ProtoContract]
    public class SomeDerivedType : SomeBaseType
    {
        [ProtoMember(1)]
        public string Name { get; set; }
    }

7、泛型中类型参数的初始化

1) default(T)

    public class RadioWrapper
    {
        private readonly T _base;

        public RadioWrapper()
        {
            this._base = default(T);
        }
    }

2) 对T添加约束

    public class RadioWrapper where T : new()
    {
        private readonly T _base = default(T);

        public RadioWrapper()
        {
            this._base = new T();
        }
    }

假如要对多个参数类型进行约束:

public DataSet MultiQuery(string connStr, IEnumerable sqlStrings)
  where Conn : DbConnection, IDisposable
  where Adapter : DbConnection, IDisposable
{
    ....
}

3) 调用CreateInstance()方法

    public class RadioWrapper where T
    {
        private readonly T _base = default(T);
        private readonly Type _type;

        public RadioWrapper()
        {
            this._type = typeof(T);
            this._base = (T)Activator.CreateInstance(this._type);
            //this._base = (T)Assembly.GetAssembly(this._type).CreateInstance(this._type.ToString());
        }
    }

8、初始化泛型类

    public class Machines
    {
        public Dictionary DictMachine { get; set; }

        public Machines()
        {
            this.DictMachine = new Dictionary();
            List names = new List() { "S1", "R1" };
            Type classType = Type.GetType("ConnectServerWrapper.RadioWrapper`1"); //获取泛型类类型,命名空间+类名
            foreach (var name in names)
            {
                Type T = Type.GetType(string.Format("gprotocol.Radio_{0}, connect_server", name)); //获取类型参数的类型,引用的类库需指明程序集名称
                Type genericType = classType.MakeGenericType(T); //替代由当前泛型类型定义的类型参数组成的类型数组的元素,并返回表示结果构造类型的 System.Type 对象
                this.DictMachine.Add(name, Activator.CreateInstance(genericType));
            }
        }
    }

9、泛型类获取、设置属性值,调用方法

1) 获取属性值

Type type = typeof(T);
T t = (T)Activator.CreateInstance(type);
PropertyInfo property = type.GetProperty("FloatList");
List float_list = (List)property.GetValue(t);
float_list.Clear();
float_list.AddRange(new float[] { 0, 0, 0 });

2) 设置属性值

Type type = typeof(T);
T t = (T)Activator.CreateInstance(type);
PropertyInfo property = type.GetProperty("FloatList");
property.SetValue(t, new List() { 0, 0, 0 });

3) 获取方法并调用

public static bool IsConnOpen(string connStr) where T : DbConnection, IDisposable
{
    Type type = typeof(T);
    T connection = (T)Activator.CreateInstance(type, connStr);
    MethodInfo openMethod = type.GetMethod("Open");
    PropertyInfo stateProp = type.GetProperty("State");
    ConnectionState state = ConnectionState.Closed;

    openMethod.Invoke(connection, null);
    state = (ConnectionState)stateProp.GetValue(connection);
}

10、CommonLib.DataUtil.OracleProvider调用存储过程返回结果集

包头:

create or replace package pag_example is
 type mycursor is ref cursor;

 Procedure p_example (var_flowid Varchar2,
            var_fremark Varchar2,
            myresult out mycursor);

end pag_example;

包体:

create or replace package body pag_example is

 Procedure p_example (var_flowid Varchar2,
            var_fremark Varchar2,
            myresult out mycursor) is
 begin

  open myresult for

   select * from table_example

 end p_example;
end pag_example;

调用过程:

OracleProvider provider = new ("localhost", "orcl", "user_name", "user_pass");
IDataParameter[] parameters = new IDataParameter[3]
{
    new OracleParameter("var_flowid", OracleDbType.Varchar2, ParameterDirection.Input) { Value = "1" },
    new OracleParameter("var_fremark", OracleDbType.Varchar2) { Value = "Q" },
    new OracleParameter("myresult", OracleDbType.RefCursor, ParameterDirection.Output)
};
DataTable dataTable = this.provider.RunProcedureQuery("pag_get_camera.p_camera", parameters).Tables[0];

11、Json.NET控制字段名称拼写方式与格式

//序列化设置
JsonSerializerSettings setting = new JsonSerializerSettings()
{
    ContractResolver = new DefaultContractResolver()
    {
        NamingStrategy = new CamelCaseNamingStrategy() //lowerCamelCase
        //NamingStrategy = new DefaultNamingStrategy() //UpperCamelCase
        //NamingStrategy = new SnakeCaseNamingStrategy() //snake_case
        //NamingStrategy = new KebabCaseNamingStrategy() //kebab-case
    },
    Formatting = Formatting.None //无特殊格式,一行输出
    //Formatting = Formatting.Indented //带缩进多行输出
};
string result = JsonConvert.SerializeObject(new JsonSource(), setting);
name demo
Default PersonName
CamelCase personName
SnakeCase person_name
KebabCase person-name

12、WPF在代码中动态添加Style

deviceStatus.Style = FindResource("FontAwesome") as Style;
deviceStatus.Text = FindResource("fa-lightbulb-o").ToString();

13、WPF在其它Style的基础上创建Style

基础Style

    

衍生Style

    

注意,基础Style一定要在衍生Style之前声明

14、string.Format格式字符串包含"{"与"}"的处理方式

因为String.Format会识别{},来用参数代替,但是如果字符串中包含{或者},则需要用{{ 来代替字符 {,用}} 代替 }
例如

json.Append(String.Format("{\"total\":{0},\"row\":{1}}", lineCount, strJSON));

运行时会报错,
若用如下代码来代替,则可以正确运行:

json.Append(String.Format("{{\"total\":{0},\"row\":{1}}}", lineCount, strJSON));

你可能感兴趣的:(C# 笔记)