C#特性Attribute的实际应用之:为应用程序提供多个版本

简介:

基于如下的几个理由,需要为应用程序提供多个版本:

1:应用程序有体验版和完整功能版;

2:应用程序测试过程中需要完成一些自动化的操作;

1:提供体验版

关于第一点,所谓体验版也就是完整版的一个缩小版。即出于某种理由,不对用户开放应用程序的全部功能。

假设我的应用程序共有两类功能。第一类功能属于单机版,而完整版还提供在线功能。那么,在功能上,我需要定制两个属性"ONLINE"和"OFFLINE"。在体验版中,我只开放"OFFLINE"功能。

要实现此目的,我不想提供两套应用程序,而是想通过最小设置,就能为一个应用程序输出两个发布版本。这个时候,就需要.NET中的特性Attribute了。

首先,我们模拟离线和在线两个功能:

 

复制代码
代码

   
   
class MyService

{

[Conditional(
" OFFLINE " )]

[Conditional(
" ONLINE " )]

public static void Testing() { System.Windows.Forms.MessageBox.Show( " offline game... " ); }



[Conditional(
" ONLINE " )]

public static void GetInfoFromNet() { System.Windows.Forms.MessageBox.Show( " online game... " ); }

}
复制代码

程序入口:

复制代码
代码

   
   
private void button1_Click( object sender, EventArgs e)

{

MyService.Testing();

}



private void button2_Click( object sender, EventArgs e)

{

MyService.GetInfoFromNet();

}

复制代码

要实现两个不同的功能,则需要在程序入口这个文件中定义:

 

复制代码

  
  
#define ONLINE

// #define OFFLINE



using System;

using System.Collections.Generic;

using System.ComponentModel;
复制代码

1.1:全局宏定义

记住,这个定义一定要在文件的最开头处。同时,该定义只对本文件有效,如果想定义全局,必须在项目属性中定义,如下:

如果想定义多个全局宏定义,则用逗号隔开,如"LUMINJI,HUCHANGJUN"。

接下来的问题,就比较简单了,如果要发布全功能,就#define ONLINE,如果要发布离线版功能,就注释掉#define ONLINE然后定义OFFLINE就行了。

2:为测试过程提供自动化操作

在测试UI的时候,需要操作各类文本框、列表等控件。举个简单的例子来说,一个登录窗口,需要输入用户名和密码。如果每次我测试的时候,都要让我自己来输入,势必影响效率。这个时候,就可以让Attribute来发挥作用了。

在如下示例中,在登录窗口的Load事件中,我们为用户名和密码赋值,并模拟点击Click事件。

复制代码
代码

   
   
#define TESTAUTO



using System;



……

public Form1()

{

InitializeComponent();

this .Load += delegate

{

TestAuto();

};

}



[Conditional(
" TESTAUTO " )]

private void TestAuto()

{

Thread t
= new Thread((ThreadStart) delegate

{

Thread.Sleep(
1000 );

this .Invoke((MethodInvoker) delegate

{

this .textBox1.Text = " luminji " ;

this .textBox2.Text = " 123 " ;

button3_Click(
this , null );

});

Thread.Sleep(
1000 );

});

t.IsBackground
= true ;

t.Start();

}


复制代码

记住,在提交代码的时候,可以注释掉TESTAUTO宏定义,这样,既不会影响到最终的版本,也能让自己在本机得到最大的自由度。从另一个角度来说,整个项目组可提前协调好,可以让这些测试方法共有。

3:关于测试多说一点:

提供一个思路:这个特性也可以让我们从程序员的角度来完成部分测试用例的编写及测试。


本文转自最课程陆敏技博客园博客,原文链接:http://www.cnblogs.com/luminji/archive/2010/11/30/1891692.html,如需转载请自行联系原作者

相关文章
|
1月前
|
编译器 C# 开发者
C# 9.0 新特性解析
C# 9.0 是微软在2020年11月随.NET 5.0发布的重大更新,带来了一系列新特性和改进,如记录类型、初始化器增强、顶级语句、模式匹配增强、目标类型的新表达式、属性模式和空值处理操作符等,旨在提升开发效率和代码可读性。本文将详细介绍这些新特性,并提供代码示例和常见问题解答。
50 7
C# 9.0 新特性解析
|
1月前
|
存储 安全 物联网
C# 在物联网 (IoT) 应用中的应用
本文介绍了C#在物联网(IoT)应用中的应用,涵盖基础概念、优势、常见问题及其解决方法。重点讨论了网络通信、数据处理和安全问题,并提供了相应的代码示例,旨在帮助开发者更好地利用C#进行IoT开发。
66 3
|
1月前
|
C# 开发者
C# 10.0 新特性解析
C# 10.0 在性能、可读性和开发效率方面进行了多项增强。本文介绍了文件范围的命名空间、记录结构体、只读结构体、局部函数的递归优化、改进的模式匹配和 lambda 表达式等新特性,并通过代码示例帮助理解这些特性。
39 2
|
1月前
|
编译器 C#
c# - 运算符<<不能应用于long和long类型的操作数
在C#中,左移运算符的第二个操作数必须是 `int`类型,因此需要将 `long`类型的位移计数显式转换为 `int`类型。这种转换需要注意数据丢失和负值处理的问题。通过本文的详细说明和示例代码,相信可以帮助你在实际开发中正确使用左移运算符。
38 3
|
1月前
|
编译器 C#
c# - 运算符<<不能应用于long和long类型的操作数
在C#中,左移运算符的第二个操作数必须是 `int`类型,因此需要将 `long`类型的位移计数显式转换为 `int`类型。这种转换需要注意数据丢失和负值处理的问题。通过本文的详细说明和示例代码,相信可以帮助你在实际开发中正确使用左移运算符。
63 1
|
1月前
|
编译器 C#
c# - 运算符<<不能应用于long和long类型的操作数
在C#中,左移运算符的第二个操作数必须是 `int`类型,因此需要将 `long`类型的位移计数显式转换为 `int`类型。这种转换需要注意数据丢失和负值处理的问题。通过本文的详细说明和示例代码,相信可以帮助你在实际开发中正确使用左移运算符。
18 0
|
1月前
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
41 3
|
9天前
|
存储 安全 编译器
学懂C#编程:属性(Property)的概念定义及使用详解
通过深入理解和使用C#的属性,可以编写更清晰、简洁和高效的代码,为开发高质量的应用程序奠定基础。
49 12
|
1月前
|
设计模式 C# 图形学
Unity 游戏引擎 C# 编程:一分钟浅谈
本文介绍了在 Unity 游戏开发中使用 C# 的基础知识和常见问题。从 `MonoBehavior` 类的基础用法,到变量和属性的管理,再到空引用异常、资源管理和性能优化等常见问题的解决方法。文章还探讨了单例模式、事件系统和数据持久化等高级话题,旨在帮助开发者避免常见错误,提升游戏开发效率。
59 4
|
3月前
|
API C#
C# 一分钟浅谈:文件系统编程
在软件开发中,文件系统操作至关重要。本文将带你快速掌握C#中文件系统编程的基础知识,涵盖基本概念、常见问题及解决方法。文章详细介绍了`System.IO`命名空间下的关键类库,并通过示例代码展示了路径处理、异常处理、并发访问等技巧,还提供了异步API和流压缩等高级技巧,帮助你写出更健壮的代码。
54 2