十七、C# 反射、特性和动态编程
DateTime dt = new DateTime();
Type type = dt.GetType();
foreach (System.Reflection.PropertyInfo property in type.GetProperties())
{
Console.WriteLine(property.Name);
}
Console.ReadLine();
using System.Diagnostics; ThreadPriorityLevel priority =
(ThreadPriorityLevel)Enum.Parse(typeof(ThreadPriorityLevel), "Idle");
using System;
using System.Diagnostics;
using System.Reflection; namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{ string[] commadnstr = new string[] { "Comparess.exe", "/Out:newFile", ": <file name>", "/Help:true", "/test:testquestion" };
string errorMessage;
CommandLineInfo commandLine = new CommandLineInfo(); if (!CommandLinHanlder.TryParse(commadnstr, commandLine, out errorMessage))
{
Console.WriteLine(errorMessage);
DisplayHelp(); }
if (commandLine.Help)
{
DisplayHelp();
}
else
{
if (commandLine.Proiroity != ProcessPriorityClass.Normal)
{
//Change thread priority
}
}
Console.ReadLine();
}
private static void DisplayHelp()
{
//Display the command-Line help.
} private class CommandLineInfo
{
public bool Help { get; set; }
public string Out { get; set; }
private ProcessPriorityClass _priority = ProcessPriorityClass.Normal;
public ProcessPriorityClass Proiroity
{
get { return _priority; }
set { _priority = value; }
} }
} public class CommandLinHanlder
{
public static void Parse(string[] args, object commandLine)
{
string errorMessage;
if (!TryParse(args, commandLine, out errorMessage))
{
throw new ApplicationException(errorMessage);
} }
public static bool TryParse(string[] args, object commandLine, out string errorMessage)
{
bool success = false;
errorMessage = null;
foreach (string arg in args)
{
string option;
if (arg[] == '/' || arg[] == '-')
{
string[] optionParts = arg.Split(new char[] { ':' }, );
//Remove the slash/dash 除去 / 和 -
option = optionParts[].Remove(, ).Trim();
optionParts[] = optionParts[].Trim(); PropertyInfo property =
commandLine.GetType().GetProperty(option,
BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public);//根据输入的字符串,获取对应的属性 if (property != null)//判断输入的有无
{
//根据属性数据类型 调用SetValue为属性set设置值
if (property.PropertyType == typeof(bool))
{
property.SetValue(commandLine, true, null);
success = true;
}
else if (property.PropertyType == typeof(string))
{
property.SetValue(commandLine, optionParts[], null);
success = true;
}
else if (property.PropertyType.IsEnum)
{
//枚举类型的设置,以及报错处理
try
{
property.SetValue(commandLine,
Enum.Parse(
typeof(ProcessPriorityClass), optionParts[], true)
, null);
success = true;
}
catch (ArgumentException)
{
success = false;
errorMessage = string.Format("The option '{0}' is invalid for '{1}'"
, optionParts[], option);
}
}
else
{
//不被支持的属性数据类型
success = false;
errorMessage = string.Format("Data type '{0}' on {1} is not supported",
property.PropertyType.ToString(),
commandLine.GetType().ToString());
}
}
else
{
//不支持的命令行选项,没有此相关属性
success = false;
errorMessage = string.Format("Option '{0}' is not supported.", option);
} } }
return success;
}
} }
public class Stack<T>
{
public void Add(T i)
{
Type t = typeof(T);
}
}
Type type;
type = typeof(System.Nullable<>);
Console.WriteLine(type.ContainsGenericParameters);
Console.WriteLine(type.IsGenericType); type = typeof(System.Nullable<DateTime>);
Console.WriteLine(type.ContainsGenericParameters);
Console.WriteLine(type.IsGenericType);
Stack<int> s = new Stack<int>();
Type t = s.GetType(); foreach (Type type in t.GetGenericArguments())
{
Console.WriteLine("Type parameter:" + type.FullName);
}
class CommandLineInfo
{
[CommandLineSwitchAlias("?")]
public bool Help
{
get { return _Help; }
set { _Help = value; }
}
private bool _Help; [CommandLineSwitchRequired]
public string Out
{
get { return _Out; }
set { _Out = value; }
}
private string _Out; public System.Diagnostics.ProcessPriorityClass Priority
{
get { return _Priority; }
set { _Priority = value; }
}
private System.Diagnostics.ProcessPriorityClass _Priority =
System.Diagnostics.ProcessPriorityClass.Normal;
} internal class CommandLineSwitchRequiredAttribute : Attribute
{
//not implimented
} internal class CommandLineSwitchAliasAttribute : Attribute
{
public CommandLineSwitchAliasAttribute(string s)
{
//not implimented
}
}
//Two Ways to do it
//[CommandLineSwitchRequired]
//[CommandLineSwitchAlias("FileName")]
[CommandLineSwitchRequired,
CommandLineSwitchAlias("FileName")]
public string Out
{
get { return _Out; }
set { _Out = value; }
}
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Chapter17")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Chapter17")]
[assembly: AssemblyCopyright("Copyright ? 2010")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] // Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("9adaf385-f1a3-474f-8a36-5c059a7a7e22")] // Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")] return:特性,出现在一个方法声明之前。
using System.ComponentModel; public class Program
{
[return: Description(
"Returns true if the object is in a valid state.")]
public bool IsValid()
{
// ...
return true;
}
}
public class CommandLineSwitchRequiredAttribute : System.Attribute
{ }
public class CommandLineSwitchRequiredAttribute : Attribute
{
public static string[] GetMissingRequiredOptions(
object commandLine)
{
List<string> missingOptions = new List<string>();
PropertyInfo[] properties =
commandLine.GetType().GetProperties(); foreach (PropertyInfo property in properties)
{
Attribute[] attributes =
(Attribute[])property.GetCustomAttributes(
typeof(CommandLineSwitchRequiredAttribute),
false);
if ((attributes.Length > ) &&
(property.GetValue(commandLine, null) == null))
{
missingOptions.Add(property.Name);
}
}
return missingOptions.ToArray();
}
}
public class CommandLineSwitchAliasAttribute : Attribute
{
public CommandLineSwitchAliasAttribute(string alias)
{
Alias = alias;
}
public string Alias
{
get { return _Alias; }
set { _Alias = value; }
}
private string _Alias;
}
class CommandLineInfo
{
[CommandLineSwitchAlias("?")]
public bool Help
{
get { return _Help; }
set { _Help = value; }
}
private bool _Help; // ...
}
PropertyInfo property =
typeof(CommandLineInfo).GetProperty("Help");
CommandLineSwitchAliasAttribute attribute =
(CommandLineSwitchAliasAttribute)
property.GetCustomAttributes(
typeof(CommandLineSwitchAliasAttribute), false)[];
if (attribute.Alias == "?")
{
Console.WriteLine("Help(?)");
};
}
public class CommandLineSwitchAliasAttribute : Attribute
{
public CommandLineSwitchAliasAttribute(string alias)
{
Alias = alias;
} public string Alias
{
get { return _Alias; }
set { _Alias = value; }
}
private string _Alias; public static Dictionary<string, PropertyInfo> GetSwitches(
object commandLine)
{
PropertyInfo[] properties = null;
Dictionary<string, PropertyInfo> options =
new Dictionary<string, PropertyInfo>(); properties = commandLine.GetType().GetProperties(
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance);
foreach (PropertyInfo property in properties)
{
options.Add(property.Name.ToLower(), property);
foreach (CommandLineSwitchAliasAttribute attribute in
property.GetCustomAttributes(
typeof(CommandLineSwitchAliasAttribute), false))
{
options.Add(attribute.Alias.ToLower(), property);
}
}
return options;
}
}
public class CommandLineHandler
{
// ...
public static bool TryParse(
string[] args, object commandLine,
out string errorMessage)
{
bool success = false;
errorMessage = null; Dictionary<string, PropertyInfo> options =
CommandLineSwitchAliasAttribute.GetSwitches(
commandLine); foreach (string arg in args)
{
PropertyInfo property;
string option;
if (arg[] == '/' || arg[] == '-')
{
string[] optionParts = arg.Split(
new char[] { ':' }, );
option = optionParts[].Remove(, ).ToLower(); if (options.TryGetValue(option, out property))
{
success = SetOption(
commandLine, property,
optionParts, ref errorMessage);
}
else
{
success = false;
errorMessage = string.Format(
"Option '{0}' is not supported.",
option);
}
}
}
return success;
} private static bool SetOption(
object commandLine, PropertyInfo property,
string[] optionParts, ref string errorMessage)
{
bool success; if (property.PropertyType == typeof(bool))
{
// Last parameters for handling indexers
property.SetValue(
commandLine, true, null);
success = true;
}
else
{ if ((optionParts.Length < )
|| optionParts[] == ""
|| optionParts[] == ":")
{
// No setting was provided for the switch.
success = false;
errorMessage = string.Format(
"You must specify the value for the {0} option.",
property.Name);
}
else if (
property.PropertyType == typeof(string))
{
property.SetValue(
commandLine, optionParts[], null);
success = true;
}
else if (property.PropertyType.IsEnum)
{
success = TryParseEnumSwitch(
commandLine, optionParts,
property, ref errorMessage);
}
else
{
success = false;
errorMessage = string.Format(
"Data type '{0}' on {1} is not supported.",
property.PropertyType.ToString(),
commandLine.GetType().ToString());
}
}
return success;
} private static bool TryParseEnumSwitch(object commandLine, string[] optionParts, PropertyInfo property, ref string errorMessage)
{
throw new NotImplementedException();
}
}
[AttributeUsage(AttributeTargets.Property)]
public class CommandLineSwitchAliasAttribute : Attribute
{
// ...
}
// Restrict the attribute to properties and methods
[AttributeUsage(
AttributeTargets.Field | AttributeTargets.Property)]
public class CommandLineSwitchAliasAttribute : Attribute
{
// ...
}
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class CommandLineSwitchAliasAttribute : Attribute
{
// ...
}
using System;
using System.IO; class Program
{
public static void Main()
{
// ...
string fileName = @"enumtest.txt";
FileInfo file = new FileInfo(fileName); file.Attributes = FileAttributes.Hidden |
FileAttributes.ReadOnly; Console.WriteLine("\"{0}\" outputs as \"{1}\"",
file.Attributes.ToString().Replace(",", " |"),
file.Attributes); FileAttributes attributes =
(FileAttributes)Enum.Parse(typeof(FileAttributes),
file.Attributes.ToString()); Console.WriteLine(attributes); // ...
}
}
#define CONDITION_A
using System;
using System.Diagnostics;
using System.Reflection;
using System.Collections.Generic; namespace ConsoleApplication2
{
public class Program
{
public static void Main()
{
Console.WriteLine("Begin...");
MethodA();
MethodB();
Console.WriteLine("End...");
} [Conditional("CONDITION_A")]
static void MethodA()
{
Console.WriteLine("MethodA() executing...");
} [Conditional("CONDITION_B")]
static void MethodB()
{
Console.WriteLine("MethodB() executing...");
}
}
}
class Program
{
public static void Main()
{
ObsoleteMethod();
} [Obsolete]
public static void ObsoleteMethod()//if you look through the warnings in the error list the warning will also show up in that list
{
}
}
[Obsolete("建议使用NewMethod()")]
public static void ObsoleteMethod()//if you look through the warnings in the error list the warning will also show up in that list
{
}
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary; namespace ConsoleApplication2
{
class Program
{
public static void Main()
{
Stream stream;
Document documentBefore = new Document();
documentBefore.Title = "before";
documentBefore.Data = "this is a data";
Document documentAfter;
//序列化
using (stream = File.Create(Environment.CurrentDirectory+"\\"+ documentBefore.Title + ".bin"))
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, documentBefore);
} //反序列化
using (stream = File.Open(Environment.CurrentDirectory + "\\" + documentBefore.Title + ".bin", FileMode.Open))
{
BinaryFormatter formatter = new BinaryFormatter();
documentAfter = (Document)formatter.Deserialize(stream);
}
} }
[Serializable]
class Document
{
public string Title = null;
public string Data = null; [NonSerialized]
public long _WindowHandle = ;
class Image
{
}
[NonSerialized]
private Image Picture = new Image();
}
}
using System;
using System.Runtime.Serialization;
[Serializable]
class EncryptableDocument : ISerializable
{
enum Field
{
Title,
Data
}
public string Title;
public string Data; public static string Ecrypt(string data)
{
string encryptedData = data;
//加密算法
return encryptedData;
}
public static string Decrypt(string encryptedData)
{
string data = encryptedData;
//解密算法
return data;
} #region 序列化与反序列化
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue(Field.Title.ToString(), Title);//name value 键值对
info.AddValue(Field.Data.ToString(), Ecrypt(Data));
} //用序列化后的数据来构造
public EncryptableDocument(SerializationInfo info, StreamingContext context)
{
Title = info.GetString(Field.Title.ToString());
Data = Decrypt(info.GetString(Field.Data.ToString())); }
#endregion
}
dynamic data = "Hello World"; Console.WriteLine(data); data = * +data.Length; Console.WriteLine(data); data = true;
Console.WriteLine(data);
XElement person = XElement.Parse(
@"<Person>
<FirstName>Inigo</FirstName>
<LastName>Montoya</LastName>
</Person>"); Console.WriteLine("{0} {1}",
person.Element("FirstName").Value,
person.Element("LastName").Value);
dynamic person = DynamicXml.Parse(
@"<Person>
<FirstName>Inigo</FirstName>
<LastName>Montoya</LastName>
</Person>"); Console.WriteLine("{0} {1}",
person.FirstName, person.LastName);
public class DynamicXml : DynamicObject
{
private XElement Element { get; set; } public DynamicXml(System.Xml.Linq.XElement element)
{
Element = element;
} public static DynamicXml Parse(string text)
{
return new DynamicXml(XElement.Parse(text));
}
//调用成员时会调用此方法,如: person.FirstName
public override bool TryGetMember(
GetMemberBinder binder, out object result)
{
bool success = false;
result = null;
XElement firstDescendant =
Element.Descendants(binder.Name).FirstOrDefault();
if (firstDescendant != null)
{
if (firstDescendant.Descendants().Count() > )
{
result = new DynamicXml(firstDescendant);
}
else
{
result = firstDescendant.Value;
}
success = true;
}
return success;
}
//设置成员值时会调用,如: person.FirstName = "text";
public override bool TrySetMember(
SetMemberBinder binder, object value)
{
bool success = false;
XElement firstDescendant =
Element.Descendants(binder.Name).FirstOrDefault();
if (firstDescendant != null)
{
if (value.GetType() == typeof(XElement))
{
firstDescendant.ReplaceWith(value);
}
else
{
firstDescendant.Value = value.ToString();
}
success = true;
}
return success;
}
}
十七、C# 反射、特性和动态编程的更多相关文章
- [.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程
[.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程 本节导读:本节主要介绍什么是.NET反射特性,.NET反射能为我们做些什么,最后介绍几种常用的 ...
- C#学习笔记四(LINQ,错误和异常,异步编程,反射元数据和动态编程)
LINQ 1.使用类似的数据库语言来操作集合? 错误和异常 异步编程 1.异步和线程的区别: 多线程和异步操作两者都可以达到避免调用线程阻塞的目的.但是,多线程和异步操作还是有一些区别的.而这些区别造 ...
- C# 4动态编程新特性与DLR剖析
=================================================== 注:很久没有发文了,贴一篇新文吧.从Word直接贴过来的,没仔细排版,诸位海涵.有关DLR和C# ...
- Java动态编程初探——Javassist
最近需要通过配置生成代码,减少重复编码和维护成本.用到了一些动态的特性,和大家分享下心得. 我们常用到的动态特性主要是反射,在运行时查找对象属性.方法,修改作用域,通过方法名称调用方法等.在线的应用不 ...
- [.NET] 《Effective C#》快速笔记 - C# 中的动态编程
<Effective C#>快速笔记 - C# 中的动态编程 静态类型和动态类型各有所长,静态类型能够让编译器帮你找出更多的错误,因为编译器能够在编译时进行大部分的检查工作.C# 是一种静 ...
- 【java编程-Javassist】秒懂Java动态编程(Javassist研究)
作者:ShuSheng007 来源:CSDN 原文:https://blog.csdn.net/ShuSheng0007/article/details/81269295 版权声明:本文为博主原创文章 ...
- 《Effective C#》快速笔记(五)- - C# 中的动态编程
静态类型和动态类型各有所长,静态类型能够让编译器帮你找出更多的错误,因为编译器能够在编译时进行大部分的检查工作.C# 是一种静态类型的语言,不过它加入了动态类型的语言特性,可以更高效地解决问题. 一. ...
- java 动态代理 和动态编程
概述 代理分两种技术,一种是jdk代理(机制就是反射,只对接口操作),一种就是字节码操作技术.前者不能算技术,后者算是新的技术.未来将有大的动作或者较为广泛的应用和变革,它可以实现代码自我的编码(人工 ...
- Java动态编程---动态代理
java中动态编程用到的技术有:反射(动态代理),javassist和ASM,这几种动态编程方法相比较,在性能上Javassist高于反射,但低于ASM,因为Javassist增加了一层抽象.在实现成 ...
随机推荐
- bzoj2120 2453
明显的数据结构题这道题的特殊性在于n只有10000,修改的操作只有1000那么就是说即便是O(n)的修改也没有太大的问题,只要常数写小一点即可考虑到以前对同色点的处理pre[i]表示与这个位置同色的前 ...
- 【JS】JS外联不执行,内联执行
匹配域名http://lb.qq.com 或 http://lb.l.qq.com
- Light OJ 1037 - Agent 47(预处理状态压缩DP)
题目大意: 有个特工要执行任务,他会遭遇到最多15个目标,特工必须把他们全部杀死.当他杀死一个目标后他可以使用目标的武器来杀死其他人.因此他必须有一个杀人的顺序,使得他开枪的次数最小. 现在给你一个表 ...
- APP界面设计之页面布局的22条基本原则
移动 APP 页面布局(Layout)是我们设计 app 界面的时候,最主要的设计任务.一个 app 的好与不好,很大部分取决于移动 APP 页面布局的合理性. 下图为 APP 最原始的布局模型. 页 ...
- HDU 4720 Naive and Silly Muggles 2013年四川省赛题
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4720 题目大意:给你四个点,用前三个点绘制一个最小的圆,而这三个点必须在圆上或者在圆内,判断最一个点如 ...
- 部署war包到Tomcat
1. 开发给到一个war包,假设叫 a-b-c.war. 2. 打开Tomcat安装路径 ,假设是“D:\Tomcat\apache-tomcat-7.0.68”,然后进入到 webapps文件夹. ...
- poj 1659 Frogs' Neighborhood (贪心 + 判断度数序列是否可图)
Frogs' Neighborhood Time Limit: 5000MS Memory Limit: 10000K Total Submissions: 6076 Accepted: 26 ...
- Java中的成员初始化顺序和内存分配过程
Java中的成员初始化顺序和内存分配过程 原帖是这样描述的: http://java.dzone.com/articles/java-object-initialization?utm_source= ...
- java第四周学习
这一周学习的还是面向对象的方法和应用 Java中方法的使用和注意事项 如果没有返回值,就不允许通过return关键字返回结果 方法中不允许嵌套使用 Return返回值只允许返回一个值,不允许返回多个 ...
- mac with windows dirver
S1: find your mac serial number on the back,like Serial No.C02Fn09GDDQW S2: baidu "苹果序列号查询" ...