一晃五年没写博客了,依旧再C#上耕耘,依旧没有啥建树,现在也不知道.net上还有多少人再使用,在这里分享一些自己觉得写的还算优雅的代码。
对于自己写着完的代码,我特别喜欢链式(来源于jQuery的影响吧),大部分时候链式就是将返回值为void类型的对象,返回this指针,直到我遇到一个特殊情况——在父类中返回子类类型。大部分情况父类都不知道子类有什么,根本没有返回子类的需求
但是由于链式调用父类的接口返回父类对象,就无法继续链式了。说明可能不清楚,直接show code
1 public class OldWhereV2<T> 2 { 3 protected Expression<Func<T, bool>> expression = null; 4 5 public OldWhereV2<T> Where(Expression<Func<T, bool>> memberExpression) 6 { 7 return this; 8 } 9 10 public OldWhereV2<T> Or(Expression<Func<T, bool>> memberExpression) 11 { 12 return this; 13 } 14 15 public OldWhereV2<T> Add(Expression<Func<T, bool>> memberExpression) 16 { 17 return this; 18 } 19 } 20 21 public class OldQeuryV2<T> : OldWhereV2<T> 22 { 23 24 public OldQeuryV2<T> Select(Expression<Func<T, object>> memberExpression) 25 { 26 return this; 27 } 28 29 public OldQeuryV2<T> Take(int count) 30 { 31 return this; 32 } 33 34 public OldQeuryV2<T> Order(Expression<Func<T, object>> memberExpression, bool asc) 35 { 36 return this; 37 } 38 }
调用的时候,如果使用链式
1 var query =new OldQeuryV2<Train>() 2 .Select(x => x.Apply_Time) 3 .Select(x => x.Apply_Time) 4 .Select(x => x.Approval_OrgName) 5 .Where(x => x.Create_Time > DateTime.Now) 6 .Add(x => x.Approval_OrgName == "") 7 .Order(x => x.Approval_OrgGID, true) 8 .Order(x => x.Apply_Time, false) 9 .Take(10);
.Order(x => x.Approval_OrgGID, true) 这行代码会报错的。因为Where返回的是OldWhereV2<T>类型,而Order方法要求OldQeuryV2<T>类型
这个问题困扰我一晚,后来我记得在哪里看过一本书,书中有泛型自包含的例子,但是当时完全看不懂,但是此处感觉使用完全没毛病所以就做了简单修改
1 public abstract class Condition<T, M> where M : Condition<T, M> 2 { 3 protected Expression<Func<T, bool>> expression = null; 4 5 public M Where(Expression<Func<T, bool>> memberExpression) 6 { 7 expression = memberExpression; 8 return (M)this; 9 } 10 11 public M Or(Expression<Func<T, bool>> memberExpression) 12 { 13 if (expression == null) 14 { 15 expression = memberExpression; 16 } 17 else 18 { 19 var invokedExpr = Expression.Invoke(memberExpression, expression.Parameters.Cast<Expression>()); 20 expression = Expression.Lambda<Func<T, bool>>(Expression.OrElse(expression.Body, invokedExpr), expression.Parameters); 21 } 22 return (M)this; 23 } 24 25 public M Add(Expression<Func<T, bool>> memberExpression) 26 { 27 if (expression == null) 28 { 29 expression = memberExpression; 30 } 31 else 32 { 33 var invokedExpr = Expression.Invoke(memberExpression, expression.Parameters.Cast<Expression>()); 34 expression = Expression.Lambda<Func<T, bool>>(Expression.AndAlso(expression.Body, invokedExpr), expression.Parameters); 35 } 36 return (M)this; 37 } 38 } 39 40 public class Qeury<T> : Condition<T, Qeury<T>> 41 { 42 List<MemberInfo> selects = new List<MemberInfo>(); 43 Dictionary<MemberInfo, bool> orders = new Dictionary<MemberInfo, bool>(); 44 int count = 1000; 45 46 public Qeury<T> Select(Expression<Func<T, object>> memberExpression) 47 { 48 MemberInfo memberInfo = memberExpression.GetMemberInfo(); 49 if (!selects.Contains(memberInfo)) 50 { 51 selects.Add(memberInfo); 52 } 53 return this; 54 } 55 56 public Qeury<T> Take(int count) 57 { 58 this.count = count; 59 return this; 60 } 61 62 public Qeury<T> Order(Expression<Func<T, object>> memberExpression, bool asc) 63 { 64 MemberInfo memberInfo = memberExpression.GetMemberInfo(); 65 if (orders.ContainsKey(memberInfo)) 66 { 67 orders[memberInfo] = asc; 68 } 69 else 70 { 71 orders.Add(memberInfo, asc); 72 } 73 return this; 74 } 75 76 public string QeurySql() 77 { 78 var queryInfo = new QueryInfo() 79 { 80 WhereExpression = this.expression, 81 SelectFields = this.selects, 82 Orders = this.orders, 83 Count = this.count 84 }; 85 86 return TableAnalysis.GetTableInfo(typeof(T)).QeurySql(queryInfo); 87 } 88 }
这里将Condition<T>类修改为Condition<T,M> 而M是Condition<T,M>的子类,返回的时候只需要返回M类型就好了,当然由于Condition返回了子类,所以我把它设置成了抽象类,但是也可以不用。由于Qeury<T> :实现了Condition<T, Qeury<T>>,所以子类就可以正常调用父类的方法了。
具体例子如下:
1 var query =new Qeury<Train>() 2 .Select(x => x.Apply_Time) 3 .Select(x => x.Apply_Time) 4 .Select(x => x.Approval_OrgName) 5 .Where(x => x.Create_Time > DateTime.Now) 6 .Add(x => x.Approval_OrgName == "") 7 .Order(x => x.Approval_OrgGID, true) 8 .Order(x => x.Apply_Time, false) 9 .Take(10);
这个算是奇技淫巧,发出来给大家看看,不过不链式不久没有烦恼了吗,正常如下面定义就好了
1 public class OldCondition<T> 2 { 3 public void Where(Expression<Func<T, bool>> memberExpression) 4 { 5 6 } 7 8 public void Or(Expression<Func<T, bool>> memberExpression) 9 { 10 11 } 12 13 public void Add(Expression<Func<T, bool>> memberExpression) 14 { 15 16 } 17 } 18 19 public class OldQeury<T> : OldCondition<T> 20 { 21 public void Select(Expression<Func<T, object>> memberExpression) 22 { 23 24 } 25 26 public void Take(int count) 27 { 28 29 } 30 31 public void Order(Expression<Func<T, object>> memberExpression, bool asc) 32 { 33 34 } 35 }
GoogleSEO是一个长期工作,并且所有的指标都是动态的,比如:网站排名,你可能会遇到这样一种情况,明明网站排名很稳定,但过了一段时间,开始下滑,这其实是一个很正常的情况。我们除了需要利用大量时间与经历提高网站排名,同时我们也需要一定时间来维护这些排名,理由很简单,竞争者无处不在。那么,如何维护网站排名的稳定呢?一尘SEO认为,除了避免GoogleSEO常犯的错误,我们在日常维护的时候,还应该遵循如下几个流程:1、内容审查运营一段时间后网站排名都会有所下滑,它可能是因为有更权威,更有效的内容排在了前面,为此,你只需要通过简单的搜索,查看首页前几名的网页,就会发现你是否需要调整内容。2、链接审查一个网站是有一个层级结构的,比如:面包屑导航,它可以清晰的解析你的目录层级,同样内链也起到相关性的作用,如果一篇文章,在站内并没有过的被提及,那么Google可以理解为它并不重要。为此,你需要适当的增加目标内容的内链,同样反向链接的建立也仍然很重要。3、改版审查如果你在近期做了非常有必要的改版,并且改动了URL地址,那么为了保持网站排名的稳定性,你可能需要提交旧链接301重定向到新链接。并且审查
2月3日,域名投资圈传言360巨资收购了域名360.com,引起一番猜测。而在次日,也就是4号,360证实了媒体的传言,确实从达沃丰手中收购了360.com,但没有对外透露具体金额。不过,坊间盛传的收购金额是1700万美金。如果属实,那么这一收购价格则是刷新了国际域名交易价格的记录。而我在域名投资者聚集的论坛和科技媒体群也看到不少人在讨论,360收购域名会对域名投资市场有什么影响?360.com为什么这么贵?周鸿祎花这么多钱买一个域名,到底是为什么?对域名市场的影响可能会集中在数字域名上,尤其是3个数字的域名价格会走高。早前360收购so.com后,推动了当时2字母域名的市场行业走高,之后360启用双拼域名haosou.com时,类似的双拼域名也受到了投资者的关注,所以可以肯定的是,这次天价收购360.com也一定会对3数字域名市场起到推动作用,短期内3数字域名市场会出现一波上涨行情。那么,一个简单的字母域名,为什么会这么贵呢?这里倒是有一个案例可以参考,就是携程。我的前老板,赢时代总裁曾荣群曾经跟我聊过携程收购xiecheng.com的经过。2011年,携程最终花300万人民币从蔡文
运算符计算机程序中最小的程序单位成为表达式,每个表达式都可以由两部分组成,即操作数和运算符。操作数可以是变量、常量、类、数组、方法等,甚至是其他表达式。而运算符则用于支出表达式中单个或者多个操作数参与运算的规则,表达式通过运算之后产生的值依赖于表达式中包含的运算符的优先级和结核性。Kotlin语言包含了Java语言中的所有运算符的特性,并结合C语言的优点,增加自定义运算符的逻辑。这些运算符之中,主要包括有:算数运算符、区间运算符、逻辑运算符、关系运算符、赋值运算符、自增自减运算符等。根据操作数的数量来划分,运算符又可以分为一目运算符、双目运算符。 -一目运算符用于单一操作对象,又称单目运算符,如:++a、!b、i–等。 -双目运算符是中置的,它拥有两个操作数,比如:a+3、a*b需要说明的是,Kotlin中没有三目运算符。基础运算符基础运算符中包含了我们在编码工程中常用的一系列运算符,使我们编写程序的基本组成部分,了解基础运算符的用法可以尽可能的避免一些语法和逻辑上的基础性错误。赋值运算符(=)赋值运算a=b,表示等号右边的b初始化或者维护等号左边的a,b可以是变量、常量、字面量或表达
转自启动CentOS系统,打开火狐浏览器,如下图所示: 2 登录“mirrors.163.com”,如下图所示: 3 点击centos后面的“centos使用帮助”,如下图所示: 4 可以看到设置和使用163的yum源的方法步骤都说的一清二楚,按照说明操作即可,特别值得注意的是“4小时更新一次”,如下图所示: 5 根据自己的CentOS系统的版本下载相应的repo文件,我的系统是CentOS6.6,所以选择下载“CentOS6”,如下图所示: 6 接下来我演示一下指令的使用。火狐浏览器下载的文件默认保存在用户主目录的Downloads文件夹中。 备份系统自带的repo文件: 指令如下: sudomv/etc/yum.repos.d/CentOS-Base.repo/etc/yum.repos.d/CentOS-Base.repo.backup 7 把163的repo文件移动到【/etc/yum.repos.d/】目录下。 指令如下:sudomvDownloads/CentOS6-Base
一、开篇这里整合分别采用了Hibernate和MyBatis两大持久层框架,Hibernate主要完成增删改功能和一些单一的对象查询功能,MyBatis主要负责查询功能。所以在出来数据库方言的时候基本上没有什么问题,但唯一可能出现问题的就是在hibernate做添加操作生成主键策略的时候。因为我们都知道hibernate的数据库本地方言会针对不同的数据库采用不同的主键生成策略。所以针对这一问题不得不采用自定义的主键生成策略,自己写一个主键生成器的表来维护主键生成方式或以及使用其他的方式来生成主键,从而避开利用hibernate默认提供的主键生成方式。所以存在问题有:怎样动态的切换数据库方言?这个问题还没有解决,没有更多时间来研究。不过想想应该可以配置两个SessionFactory来实现,那又存在怎么样动态切换SessionFactory呢?!需要解决这个问题才行,而这里则演示怎么样动态切换DataSource数据源的方法。 二、代码演示在演示开始之前你的项目已经成功的整合完成的情况下才行,如果你还不知道怎么使用Spring整合MyBatis和Spring整合Hibernat
效果演示:http://pcik.7di.net/pcik_reg 百度的效果演示:https://passport.baidu.com/cgi-bin/genimage?captchaservice63636236364e55367233302f31673844526b664451665a5a4d4977466974376b707a754466777934697449455561625171346c725055444b51734a35376d2b4f744b6d303238315341382b354675344c3153745869487252376169752b437450515138574972436752584f53717849726f48593258666c373574593753614f4d32703831724e51722b694a31756b67467137644c30506979496639594e504931536732687a5a505379305544554245724f76694a307247632b4f76426165663144732b595359394
1.背景: 虚拟机安装的luajit 没有cjson库,就不能对table进行编码操作,手动安装一个。 2.安装: cjson下载地址:http://www.kyne.com.au/~mark/software/lua-cjson.php 下载文件 lua-cjson-2.1.0.tar.gz 放到虚拟机一个目录,解压,先make一下 cc-c-O3-Wall-pedantic-DNDEBUG-I/usr/local/include-fpic-olua_cjson.olua_cjson.c lua_cjson.c:43:17:error:lua.h:Nosuchfileordirectory lua_cjson.c:44:21:error:lauxlib.h:Nosuchfileordirectory lua_cjson.c:192:error:expected‘)’before‘*’token lua_cjson.c:206:error:expected‘)’before‘*’token lua_cjson.c:218:error:expecte
传送门啦 思路: $f[i][j]$表示从$i$开始,包含$1<<j$个元素的区间的区间最大值; 转移方程:$f[i][j]=max_(f[i][j-1],f[i+(1<<j-1)][j-1]$; 查询$(l,r)$: $p=log_2(r-l+1)$; $max(l,r)=max(f[l][p],f[r-(1<<p)+1][p])$; #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #definereregister usingnamespacestd; intn,m,a[100005],l,r; intf[10000010][21]; inlineintread(){ intf=1,x=0; charch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} w
BFS算法 上一篇文章讲解了DFS深度优先遍历的算法,我们说DFS顾名思义DEEPTHFIRET,以深度为第一标准来查找,以不撞南墙不回头的态度来发掘每一个点,这个算法思想get到了其实蛮简单。那么BFS和DFS有什么相同点和不同点呢? 我觉得有一种比喻对于DFS和BFS从方法论的角度解释很到位,DFS就像是小明要在家里找到钥匙,因为对位置的不确定,所以一间一间的来找,深度遍历能确保小明走过所有的屋子。而BFS像是近视的小明的眼镜掉在了地上,小明肯定是先摸索离手比较近的位置,然后手慢慢向远方延伸,直至摸到眼镜,像是以小明为中心搜索圈不断扩大的过程。所以如果说DFS从遍历的层次结构上类似树的先序遍历,那么BFS算法按照里外顺序逐渐增加深度的做法,就像极了朴素的层次遍历,例如: 把左图拉平,按照层序把结点排列下来,各节点的连接关系并没有变,图结构没有发生变化,但是这时,我们从A出发,按层序遍历可以得到顺序是ABFCIGEDH 结合上一篇文章的DFS,我们可以发现这两种算法的区别在每一个点上都能得以体现,比如A点,DFS鼓励结点向着一个方向冲,BFS则会在一个点上按照顶点下标次
断断续续理了一下关于channel的一些概念,现在可以把下面的程序理清楚了。 1.sourcecode 这个程序来自于《Go语言程序设计》7.2.2并发的Grep,程序如下。 packagemain import( "bufio" "bytes" "fmt" "io" "log" "os" "path/filepath" "regexp" ) typeJobstruct{ filenamestring resultschan<-Result } typeResultstruct{ filenamestring finoint linestring } varnumberOfWorkers=4 funcmain(){ //retrieveinputarguments iflen(os.Args)<3||os.Args[1]=="-1"||os.Args[1]=="--help"{ fmt.Printf("usage:%s<regrex><files>\n",filepath.Base(os.Args[0])) os.Exit(1) } i
迎接2022:数字化浪潮下五位IT大咖给CIO的十大建议_亿信华辰-大数据分析、数据治理、商业智能BI工具与服务提供商(esensoft.com) 2021医药大健康CIO沙龙于12月18日在无锡顺利召开。在高端对话环节,企业网D1NetCEO范脡、扬子江药业CIO张爱军、艾兰得副总裁CIO蒋科伟、泰格医药集团副总裁段培军、天士力CIO李福生、中科智康副总裁(原复星医药CIO)黄邦瑜,就如何调动业务的积极性进行数字化转型?如何提升IT团队在企业中的地位?如何尽快做出数字化转型成绩等话题展开深入探讨,小编根据现场内容整理出五位IT大咖给CIO提出的十大建议,希望在2022年为CIO的数字化转型推进工作提供一些启发。 善于与老板沟通 五位嘉宾在对话中都非常认可与老板沟通的重要性,中科智康副总裁(原复星医药CIO)黄邦瑜认为,从互联网转型到数字化转型,每当新的概念兴起时老板迫于业绩的压力都会产生焦虑,CIO可以利用好这些契机与老板深入沟通,一方面了解老板是否下定了改革的决心,另一方面
铛~铛~铛~Docker即将颠覆整个软件产业,从云计算平台到软件开发、测试,整个SDLC都会极度依赖Docker。 圈子里面一定有很多讨论Docker的话题,简而言之,Docker其实只解决一个问题: QA:程序无法启动!!! DEV:不可能,我的机器上可以运行 大家可以慢慢体会以上对话。但无论怎样,对于已经投入SSD怀抱的同学们来说,要在宝贵的SSD上存放50个大小为800MB左右不等的DockerImage是绝对不可以接受的!!但偏偏从DockerHub上下载到的Image,大部分都是这个数字,甚至远大于这个。看着逐渐被Docker侵蚀的磁盘空间,楼主决定给Docker文件进行大瘦身。结果发现效果很显著,请看下图 颤抖吧,凡人!100MB的Redis压缩到只有7MB!!! 首先纠正一下基本概念: 1.Docker不是虚拟机(切记) 2.Docker里面的程序运行时不需要完整的操作系统! 3.CoreOS,RHEL,Ubuntu,CentOS,等等等,它们都是一个操作系统! 怎么做到的,基本就是以下几个步骤 1.使用B
第二章 罗马大厅 德乔治1946年到达罗马时,这座城市已经屈膝了。首先,是很难到达,因为铁路线被严重损坏。然后是政治不稳定和贫穷;整个基础设施都被摧毁,公共运输几乎不存在。从城市的一端搬出去很困难对另一个。尽管如此,埃尼奥还是很高兴,因为他发现由于墨索里尼试图聚集那里有意大利最好的大学教授。 在罗马,埃尼奥可以依靠他姐姐的帮助:“我们互相陪伴。我们经常在教学楼里碰面,沿着大学的林荫大道散步“区域”-记得罗莎-“或者他,作为一个强壮的步行者,来参观修女旅社,我在那里通过盖塔住宿。在那里他很受我同事的喜爱他与大多数大学生的看法不同矜持,善良,深思熟虑,总是乐于助人或解释一些数学知识发布。” 多亏了他姐姐,他找到了住处。他家里有个房间罗莎的一个朋友的家。父亲加斯帕雷·格雷科也是萨伦托人像恩尼奥这样的地区,曾是意大利中央银行的出纳员母亲,路易莎,是一个家庭主妇,最初来自罗马省唯一的儿子安东尼奥和恩尼奥年龄一样大。他们住在白宫前的VialedelRe银行(后来成为VialeTrastevere)教育部所在地。 安东尼奥·格雷科清楚地记得埃尼奥到达罗马的那天。“我去见他在罗马火车站,但我错过了他。
您的网络必须有能力去区别这一个地址有别于其它的地址。这个东西叫做节点 3.TCP/IP(TransmissionControlProtocol/InternetProtocol的简写,中文译名为传输控制协议/互联网络协议)协议是Internet最基本的协议,简单地说,就是由底层的IP协议和TCP协议组成的。在Internet没有形成之前,各个地方已经建立了很多小型的网络,称为局域网,Internet的中文意义是“网际网”,它实际上就是将全球各地的局域网连接起来而形成的一个“网之间的网(即网际网)”。然而,在连接之前的各式各样的局域网却存在不同的网络结构和数据传输规则,将这些小网连接起来后各网之间要通过什么样的规则来传输数据呢?这就象世界上有很多个国家,各个国家的人说各自的语言,世界上任意两个人要怎样才能互相沟通呢?如果全世界的人都能够说同一种语言(即世界语),这个问题不就解决了吗?TCP/IP协议正是Internet上的“世界语”。TCP/IP协议的开发工作始于70年代,是用于互联网的第一套协议。 协议,网络协议的简称,网络协议是通信计算机双方必须共同遵从的一组约定。如怎么
Serializationistheprocessofconvertingadatastructureorobjectintoasequenceofbitssothatitcanbestoredinafileormemorybuffer,ortransmittedacrossanetworkconnectionlinktobereconstructedlaterinthesameoranothercomputerenvironment. Designanalgorithmtoserializeanddeserializeabinarytree.Thereisnorestrictiononhowyourserialization/deserializationalgorithmshouldwork.Youjustneedtoensurethatabinarytreecanbeserializedtoastringandthisstringcanbedeserializedtotheoriginaltreestructure. Example: Youmayserializet
<!DOCTYPEhtml> <htmllang="en"> <head> <metacharset="UTF-8"> <title>时钟</title> <scripttype="text/javascript"> functiontoDouble(num)//不满两位,空位补零 { if(num<10) { return'0'+num;//一位数前面加零,就变为两位数 } else { return''+num; } } window.onload=function()//程序主体运行内容 { varoBtn=document.getElementById('btn1'); varaImg=document.getElementsByTagName('img'); vari=0; functionupdateTime() { varoDate=newDate();//获取系统时间 varstr=toDouble(oDate.getHours())+toDouble(oDate.getMinut
#入门Java编程的简单引导# 想要学习Java编程,我们首先需要Java的工作环境JDK,然后是一个编程环境软件IDE,最后也是最重要的部分,找一本前辈写的书籍,开始一步一步的学。 +JDK:http://www.oracle.com/technetwork/java/javase/downloads/index-jsp-138363.html#javasejdk点击JDKDownload图标,在下载页面点击Accept,然后选择合适平台的版本下载。 +IntelliJIDEA:https://www.jetbrains.com/idea/点击下载,选择Community版。 +Java核心技术卷1基础知识原书第9版:http://pan.baidu.com/s/1jIvHY8A注意!只看1-6、11-14章,其他的部分已经过时、作废。 其次,我们还需要一些知识、信息作为辅助。以下是一个Java学习者平日里收集的相关网站: +Java在线文档:http://tool.oschina.net/apidocs/apidoc?api=jdk_7u4 +JavaFX(图形用户界面)中文网站:
pip3installjieba-0.39.zippip3installdocutils-0.15.2-py3-none-any.whlpip3installpython_dateutil-2.8.0-py2.py3-none-any.whl Requirementalreadysatisfied:six>=1.5pip3installbotocore-1.12.238-py2.py3-none-any.whlpip3installs3transfer-0.2.1-py2.py3-none-any.whlpip3installjmespath-0.9.4-py2.py3-none-any.whlpip3installsmart_open-1.8.4.tar.gzpip3installboto-2.49.0-py2.py3-none-any.whlpip3installscipy-1.3.1-cp37-cp37m-manylinux1_x86_64.whlpip3installnumpy-1.17.2-cp37-cp37m-manylinux1_x86_64.whl pip3ins
一、简介 eXtendsible markuplanguage 可扩展的标记语言 可以用来: 1. 可以用来保存数据 2. 可以用来做配置文件 3. 数据传输载体 二、说明(可以用eclipse编写xml哦) 1,顶部一定是文档声明 简单声明,version:解析这个xml的时候,使用什么版本的解析器解析 <?xmlversion="1.0"?> encoding:解析xml中的文字的时候,使用什么编码来翻译 <?xmlversion="1.0"encoding="gbk"?> standalone:no-该文档会依赖关联其他文档,yes--这是一个独立的文档//一般用不到 <?xmlversion="1.0"encoding="gbk"standalone="no"?> 复制 > 我们的电脑默认文件保存的时候,使用的是GBK的编码保存 2,只有一个根标签 3,标签元素、属性、注释和html类似 4,CDATA区: 如