iupme

2012年1月28日 #

类的智能化设计_后期添加任意功能

当一个类设计好后.它的属性.字段,方法等都会固定下来.如果要在后期添加新功能.有多种办法

1,直接修改.  用于类比较小,修改的地方也少.就这样直接修改

2,继承一个接口,然后实现接口. 这是常用的.体现了继承的优点. 也有缺点.当类比较多时候.要全部都修改.

3,适配器模式.新建一个类,传入原对象.并继承接口.体现了低耦合,高内聚.如:


     

  internal interface I新功能
    {
        void 飞();
    }

    internal class 新对象 : I新功能
    {
        private 对象 _对象;

        public 新对象(对象 对象1)
        {
            _对象 = 对象1;
        }

        #region I新功能 Members

        public void 飞()
        {
        }

        #endregion
    }

 

下面要介绍的是让类拥有学习功能.在后期如果再要添加功能就可以学习后再使用.

先让类继承于 智能化接口. 再建立针对于这个类的学校. 当对象需要新功能的时候.就让对象去学校学习.

然后就可以调用对象的新功能了.

 

  internal interface I智能化
    {
        /// <summary>
        /// int 为技能的哈希码. obj为技能.
        /// </summary>
        /// <value>The 技能.</value>
        Dictionary<int, object> 技能 { get; set; }

        /// <summary>
        /// T 为学会的技能
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        T 使用<T>();
    }

    internal interface I学校
    {
        /// <summary>
        /// T 为要学习的技能
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="智能对象">The 智能对象.</param>
        void 教学<T>(I智能化 智能对象);
    }

    internal class 学校 : I学校
    {
        #region I学校 Members

        public void 教学<T>(I智能化 智能对象) //可以有限制,或者其他限制
        {
            var h = typeof (T).GetHashCode();
            if (智能对象.技能.ContainsKey(h))
            {
                return; //存在技能就返回.
            }
            T 新技能 = default (T); //此处可以对技能做更多操作初始化.
            智能对象.技能.Add(h, 新技能);
        }

        #endregion
    }


    internal class 飞
    {
        public void 飞翔()
        {
            //...
        }

        public void 降落()
        {
        }
    }

 

上面建立了通用的智能化接口. 学校接口.和一个新技能飞翔.

下面是对象的建立.


internal class 对象 : I智能化
    {
        public 对象()
        {
            技能 = new Dictionary<int, object>();
        }


        #region I智能化 Members


        public T 使用<T>()
        {
            int h = typeof (T).GetHashCode();
            if (技能.ContainsKey(h))
            {
                return (T) 技能[h];
            }
            return default(T);
        }


        public Dictionary<int, object> 技能 { get; set; }


        #endregion
    }

 
 对象拥有技能列表.我还没找到怎么用泛型代替.先用万能对象.
客户端调用如下:

 internal class 客户
    {
        private  对象 对象1;

        public 客户()
        {
            对象1 = new 对象();
            演示();
        }

        private void 演示()
        {
            I学校 学校1 = new 学校();
            学校1.教学<飞>(对象1);
            对象1.使用<飞>().飞翔();
        }
    }

 

学校可以对不同的类教学不同的技能, 可以泛型化.

具体表现有更多可以优化的地方.先记录下来,抛砖引玉.

posted @ 2012-01-28 15:35 iupme 阅读(281) 评论(0) 编辑

2011年5月18日 #

取得音频文件长度

使用了事件返回 音频长度.

大部分用的是中文名称.注释就不写了.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Threading;

namespace 编程帮助
{
public interface II媒体长度
{
void 歌曲长度(string filename);
TimeSpan 检测超时时间 {
get; set; }
event EventHandler<E媒体长度> 长度报告;

}

public class E媒体长度 : EventArgs
{
public E媒体长度(string 文件, TimeSpan 长度)
{
this.文件 = 文件;
this.长度 = 长度;
}

public string 文件 { get; set; }

public TimeSpan 长度 { get; set; }
}

public class CC媒体长度 : II媒体长度
{
System.Windows.Media.MediaPlayer p;
private string 歌曲;
public event EventHandler<E媒体长度> 长度报告 = delegate { };
private TimeSpan 长度;
private DispatcherTimer 时间线;


public CC媒体长度()
{
歌曲
= string.Empty;
长度
= TimeSpan.Zero;
p
= new System.Windows.Media.MediaPlayer();
p.IsMuted
= true;
p.MediaFailed
+= new EventHandler<System.Windows.Media.ExceptionEventArgs>(p_MediaFailed);
p.MediaOpened
+= new EventHandler(p_MediaOpened);
时间线
= new DispatcherTimer();
时间线.Interval
= TimeSpan.FromSeconds(5); //超时时间
时间线.Tick += new EventHandler(时间线_Tick);
}

void 时间线_Tick(object sender, EventArgs e)
{
零长度报告();
}

void p_MediaOpened(object sender, EventArgs e)
{
长度
= (p.NaturalDuration.HasTimeSpan) ? p.NaturalDuration.TimeSpan : TimeSpan.Zero;
标准长度报告();
}

void p_MediaFailed(object sender, System.Windows.Media.ExceptionEventArgs e)
{
零长度报告();
}

private void 零长度报告()
{
长度
= TimeSpan.Zero;
标准长度报告();
}

private void 标准长度报告()
{
时间线.Stop();
p.Stop();
长度报告(
this, new E媒体长度(歌曲, 长度));
}

public void 歌曲长度(string filename)
{
try
{
p.Close();
歌曲
= filename;
时间线.Start();
p.Open(
new Uri(filename));

}
catch (Exception)
{
零长度报告();
}

}

public TimeSpan 检测超时时间
{
get { return 时间线.Interval; }
set { 时间线.Interval = value; }
}

}

}

posted @ 2011-05-18 14:43 iupme 阅读(211) 评论(0) 编辑

WPF 多线程工作

第1种用 Task类. 推荐用这个办法

public void 工作_Task()
{
Dispatcher x
= Dispatcher.CurrentDispatcher;//取得当前工作线程
//另开线程工作
Task<int> 计数 = new Task<int>(() => { return 计数方法(); });
计数.ContinueWith(工作完毕后方法);
//工作完毕后执行的方法
计数.Start();//开始工作

}
public void 工作完毕后方法(Task<int> 参数)
{
if (参数.IsCompleted) //正常工作完毕
{
var 结果
= 参数.Result; //取得结果
//处理结果.
//本方法非界面线程.如果需要在界面线程操作,需要转移到界面线程
}
}

int c;
public int 计数方法()
{
return c++;
}

第2种方法用线程.

public void 工作_Thread()
{
Dispatcher x
= Dispatcher.CurrentDispatcher;//取得当前工作线程
//另开线程工作
System.Threading.ThreadStart start = delegate()
{
//工作函数
Func<string> fu = new Func<string>(() => { return ""; });//工作函数
var 工作结果 = fu();//开始工作

//异步更新界面
x.BeginInvoke(new Action(() =>
{
//在界面线程操作 可以使用 工作结果
}), DispatcherPriority.Normal);
};
new System.Threading.Thread(start).Start(); //启动线程
}

第3种方法用 BackgroundWorker.

这种方法介绍的比较多了.就不说了.

BackgroundWorker 后台线程;
public void 线程初始化()
{
后台线程
= new BackgroundWorker();
后台线程.WorkerSupportsCancellation
= true; //可以取消
后台线程.DoWork += new DoWorkEventHandler(后台线程_DoWork);
后台线程.RunWorkerCompleted
+= new RunWorkerCompletedEventHandler(后台线程_RunWorkerCompleted);
}
public void 启动后台线程()
{
后台线程.RunWorkerAsync();
}

void 后台线程_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//工作完毕的方法
}

void 后台线程_DoWork(object sender, DoWorkEventArgs e)
{
//工作方法
}

posted @ 2011-05-18 13:43 iupme 阅读(353) 评论(0) 编辑

2011年4月20日 #

监听WPF 属性改变.

针对WPF 的依赖属性.可以监听后,添加自己的事件处理程序;
 属性名称 需要是依赖属性名,
控件可以是监听的类型.
DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(属性名称, typeof(控件名称));
            if (dpd != null)
            {
                dpd.AddValueChanged(控件实例, delegate
                {
                     //处理程序
                });
            }
 示例:
View Code
DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(UC登录.登录成功Property, typeof(UC登录));
if (dpd != null)
{
dpd.AddValueChanged(uC登录1,
delegate
{
if (uC登录1.登录成功 )
{
this.Close();
}
});
}
 
 
 
 
 
 

posted @ 2011-04-20 15:16 iupme 阅读(199) 评论(0) 编辑

2011年4月16日 #

C# List列表内数据移动顺序(上下调整)

有时候需要调整数据列表内的顺序.

现写成扩展方法.方便调用.

View Code
public static partial class KK扩展方法
{
/// <summary>
/// KK上移s the specified data list.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dataList">The 数据列表 list.</param>
/// <param name="id">The 需要移动的id.</param>
/// <param name="位数">The 移动的 位数. 默认为1</param>
/// <returns></returns>
public static bool kk上移<T>(this IList<T> dataList, int id, int 位数 = 1)
{
return dataList.kk移动(id, id - 位数);
}

public static bool kk下移<T>(this IList<T> dataList, int id, int 位数 = 1)
{
return dataList.kk移动(id, id + 位数);
}

public static bool kk顶部<T>(this IList<T> dataList, int id)
{
return dataList.kk移动(id, 0);
}

public static bool kk底部<T>(this IList<T> dataList, int id)
{
return dataList.kk移动(id, dataList.Count - 1);
}

public static bool kk移动<T>(this IList<T> dataList, int 原ID, int 新ID)
{
if (原ID >= dataList.Count || 新ID >= dataList.Count || 原ID < 0 || 新ID < 0 || 原ID == 新ID) { return false; }

try
{
var sel
= dataList[原ID];
dataList.RemoveAt(原ID);
dataList.Insert(新ID, sel);
return true;
}
catch (Exception)
{
return false; ;
}

}


public static bool kk交换<T>(this IList<T> list, int 原ID, int 新ID)
{
if (原ID >= list.Count || 新ID >= list.Count || 原ID < 0 || 新ID < 0 || 原ID == 新ID) { return false; }

try
{
var sel
= list[原ID];
list[原ID]
= list[新ID];
list[新ID]
= sel;
return true;
}
catch (Exception)
{
return false; ;
}


}
}

posted @ 2011-04-16 20:47 iupme 阅读(385) 评论(0) 编辑

WPF 界面专用属性


WPF 专用属性,可以实现界面自动更新.

类需要继承自 DependencyObject

需要引用: using System.Windows;

属性声明如下.  用代码片段 输入比较快.  按dp +tab+tab + 0 完成.

代码片段下载:http://drwpf.com/blog/2010/04/30/updated-code-snippets/
 #region IsSwanky

        /// <summary>
        /// IsSwanky Dependency Property
        /// </summary>
        public static readonly DependencyProperty IsSwankyProperty =
            DependencyProperty.Register("IsSwanky", typeof(bool), typeof(类名),
                new FrameworkPropertyMetadata((bool)false));

        /// <summary>
        /// Gets or sets the IsSwanky property. This dependency property
        /// indicates ....
        /// </summary>
        public bool IsSwanky
        {
            get { return (bool)GetValue(IsSwankyProperty); }
            set { SetValue(IsSwankyProperty, value); }
        }

        #endregion


WPF  绑定数据专用列表:

ObservableCollection<T>

可以实现界面自动更新.需要引用 :

using System.Collections.ObjectModel;

如果需要在界面上显示的基本上就用这个列表了.可以替代 List<T>, 不知道能不能传入到后台线程处理数据.

用的DependencyProperty 属性就不能传入后台处理.还要写个CLR类传到后台处理. 还在找其他的办法.


 

posted @ 2011-04-16 19:57 iupme 阅读(285) 评论(1) 编辑

2011年4月15日 #

C#程序自动关机

用程序自动关机.

下面是关机方法,调用了系统自带的关机命令. 如果需要定时关机.只需要用定时器.到时间调用此命令即可.

View Code
public static void 关机(string 运行命令 ="shutdown -s -t 30")
{
var s
= 运行命令;
if (string.IsNullOrEmpty(s)) { return; }
string 程序 = string.Empty;
string 参数 = string.Empty;
int a = s.IndexOf(" ");
if (a < 0)
{
程序
= s;
}
else
{
程序
= s.Substring(0, a);
参数
= s.Remove(0, a);
}

System.Diagnostics.Process 进程
= new System.Diagnostics.Process();
进程.StartInfo.FileName
= 程序;
进程.StartInfo.Arguments
= 参数;
进程.Start();

}

posted @ 2011-04-15 22:53 iupme 阅读(160) 评论(0) 编辑

C#更改系统时间

有时候需要调整系统时间来测试程序.

用DOS命名可以做到.此方法也可以运行其他DOS 命令.或者其他程序.

方法如下:

public void cmd()
{
var process
= new Process();
process.StartInfo.FileName
= "cmd.exe";
process.StartInfo.UseShellExecute
= false;
process.StartInfo.RedirectStandardInput
= true;
process.StartInfo.RedirectStandardOutput
= true;
process.StartInfo.RedirectStandardError
= true;
process.StartInfo.CreateNoWindow
= true;
process.Start();


//在需要的地方写入命令
process.StandardInput.WriteLine("time 0" );
}

posted @ 2011-04-15 22:08 iupme 阅读(137) 评论(0) 编辑

C#自带的合并字符串列表

有时候用到要把字符串的列表 合并.以前是自己写个方法.

现在.NET 4有自己的方法了.

  public void 合并字符串()
        {
            var stringlist = new List<string>() { "你", "我", "他" };

            var 连接整个字符 = string.Concat(stringlist);

            var 连接字符并换行 = string.Join("\r\n", stringlist);
        
        }

还有一个新类型比较好用: 元组.

 当一个方法需要返回多个数据的时候.用用.或者要临时传递多参数时.

 public 元组()
       {

           //可以声明1到8个或更多.
           //用途:
           //可以传递多个参数,返回多个参数.
           Tuple<string, string, int> 临时组合类 =
               new Tuple<string, string, int>("姓名","年龄",18);


           //也可以声明匿名类.
           var 新类 = new { 姓名 = "", 性别 = "" };

       }

posted @ 2011-04-15 22:02 iupme 阅读(210) 评论(0) 编辑

取得汉字首字母.或者拼音

需要引用 微软的 一个拼音控件.
using Microsoft.International.Converters.PinYinConverter;
可以在微软官方下载 CHSPinYinConv.msi.安装即可引用
缺点:无法识别重音字.
已经声明为扩展方法.任何汉字字符串都可以调用了.
方法名有kk是为了在引用的时候输入更快定位到扩展方法.
public static partial class KK扩展方法
{
public static string kk拼音首字母(this string 汉字)
{
StringBuilder r
= new StringBuilder();
foreach (var item in 汉字)
{
if (ChineseChar.IsValidChar(item)) //是汉字 返回首字母
{
r.Append(
new ChineseChar(item).Pinyins[0][0]);
}
else if (char.IsNumber(item)) //是数字 返回本身
{
r.Append(item);
}
else if (char.IsLetter(item)) //是字母 转大写
{
r.Append(
char.ToUpper(item));
}
}
return r.ToString();
}
}
查找速度比较快的是查找表
字母表上传不上,可以网上搜索出来. 基本是1毫秒查找1万字.
方法如下:
View Code
public static string Get汉字首字母(string 字符串)
{
if (string.IsNullOrEmpty(字符串)) return string.Empty;
var 结果
= new StringBuilder();
foreach (char vChar in 字符串)
{
int c = (int)vChar - 19968;
if ((vChar >= '0' && vChar <= '9') || (vChar >= 'a' && vChar <= 'z') || (vChar >= 'A' && vChar <= 'Z')) // 若是字母和数字则直接输出
结果.Append(char.ToUpper(vChar));
else if (c >= 0 && c < 20902) // 对可以查找的汉字计算它的首拼音字母的位置,然后输出
{
结果.Append(首字母表[c]);
}
}
return 结果.ToString();
}
 
本想自己生成字母表的.结果是不能用.方法如下:
 
View Code
public string 字母表(int 开始 = 19968, int 结束 = 40870)
{
StringBuilder r
= new StringBuilder();
string cr;
for (int i = 开始; i < 结束; i++)
{
cr
= char.ConvertFromUtf32(i);
if (ChineseChar.IsValidChar(cr[0]))
{
//好像不全.只能输出20538个字母
r.AppendLine(string.Format("{0} {1} {2} ", i.ToString(), cr, new ChineseChar(cr[0]).Pinyins[0][0]));
//r.Append(string.Format("{0}", new ChineseChar(cr[0]).Pinyins[0][0]));
}
}
return r.ToString();
}

posted @ 2011-04-15 09:14 iupme 阅读(210) 评论(3) 编辑

仅列出标题  下一页

导航

统计信息

News