当前位置:  编程技术>.net/c#/asp.net

基于C# 中可以new一个接口?的问题分析

    来源: 互联网  发布时间:2014-10-20

    本文导语:  如果有人问你,C# 中可以new 一个接口吗?,你会怎么回答? 假设ITestInterface 是一个接口,那么这样的代码是否有问题? ITestInterface testInterface = new ITestInterface(); 很多书上都会说,当然有问题,接口不能用new ,然后你就认为上...

如果有人问你,C# 中可以new 一个接口吗?,你会怎么回答?

假设ITestInterface 是一个接口,那么这样的代码是否有问题?

ITestInterface testInterface = new ITestInterface();

很多书上都会说,当然有问题,接口不能用new ,然后你就认为上面这句语句肯定通不过编译器的编译了。

可是凡事无绝对,C# 竟然允许你这么写,当然你需要加点”料”才行。

在VS2005 中新建控制台程序CA2005.添加 Microsoft.Office.Interop.Excel 引用

Program 的Main函数只有一句话:

注意,可以通过编译,看下Application的定义:

很明显Application 是个interface,

这里我要扯一下,经常看到有人说string 是类还是结构什么的,看下string 的定义:

 String 是用class 来修饰的,所以string 100% 是类。

还是扯回来吧,Application 是个接口,但是我们却可以用new  .为什么 ?

先看下反编译后的代码吧:

 

可以看到虽然我们写的是new Application,但是编译器为我们生成的却是new ApplicationClass();

难道Application 有什么特别的地方?

仔细的同学一眼就看出了Application是被这两个特性修饰的:

[CoClass(typeof(ApplicationClass))]

[Guid("000208D5-0000-0000-C000-000000000046")]

关于CoClass的解释可以看msdn:

 

有些人不喜欢看msdn,而喜欢看博客的一个原因就是msdn太不直白了。

我个人的理解是CoClass 就好像concrete Class(具体类)。

这个特性指示编译器在编译Application的时候,使用ApplicationClass 来实现。

回到上面的最初的问题上:

如何让这段代码通过编译:

ITestInterface testInterface = new ITestInterface();

通过上面的分析,我们很容易将这个特性来修饰我们的自己的接口:

namespace CA2005

{

    [CoClass(typeof(TestClass))]

    [Guid("6C8BF7FE-1F6B-437E-BCC8-6D2FF04E66B3")]

    public interface ITestInterface

    {

        void DoSomething();

    }

    [Guid("68C7CB18-0DEE-4689-845D-741525281C76")]

    public class TestClass : ITestInterface

    {

        public void DoSomething()

        {

            Console.WriteLine("TestClass:DoSomething");

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            Microsoft.Office.Interop.Excel.Application excelApplication =

                new Microsoft.Office.Interop.Excel.Application();

            ITestInterface testInterface = new ITestInterface();

            testInterface.DoSomething();

        }

    }

}

编译,结果如下:

接口被标记了CoClassAttribute,而不是ComImportAttribute.

原来想要new 一个接口使用的是编译器对COM的优化和支持。

很明显上面的Application是一个COM对象,所以可以new Application

 

在ITestApplication中添加ComImportAttribute 特性:

再次运行,结果如下:

查看下反编译的代码:

之所以我对VS2005 用红色字体,是因为如果你用VS2010 创建的程序,那么你会看到不一样的反编译结果:

public static void Main()

{

      Application application1 = (Application) Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("00024500-0000-0000-C000-000000000046")));

      ITestInterface interface1 = new TestClass();

      interface1.DoSomething();

      Console.ReadLine();

}

这里的Type.GetTypeFromCLSID 中的guid是ApplicationClass的Guid,也就是CoClass中Type的Guid:

[ComSourceInterfaces("Microsoft.Office.Interop.Excel.AppEvents")]

    [Guid("00024500-0000-0000-C000-000000000046")]

    [TypeLibType(2)]

    [ClassInterface(0)]

    public class ApplicationClass : _Application, Application, AppEvents_Event

{

}

这点一定要注意。

楼下有些同学说这有什么意义,下面是我的项目实例,也是这个问题才让我研究了这个问题:

在项目中使用了一种C3读卡器,这种读卡器提供了读卡接口(C3ReadCard),但是开发环境是2005,所以不能够C3ReadCard c3=new C3ReadCard();

这点很奇怪,Excel的可以new,但是C3ReadCard却不可以new,但是通过反射去调用实现类就可以使用C3ReadCard的接口。

这个问题的意义在于你明白编译器如何去处理new一个接口所生成的代码,也许还有其他的用处,等待你的发现。


    
 
 

您可能感兴趣的文章:

  • C#判断ip地址是否可以ping的通
  • C# Winform 让整个窗口都可以拖动
  • c#不使用系统api实现可以指定区域屏幕截屏功能
  • C#中判断某类型是否可以进行隐式类型转换
  • c#调用api控制windows关机示例(可以重启/注销)
  • asp.net(C#)生成Code39条形码实例 条码枪可以扫描出
  • LINUX下最大支持虚接口数是多少? 如果我想配置1000个虚接口可以吗?
  • 菜鸟提问:一个类实现了一个接口,除了要定义接口的所有方法外,可不可以再添加其他方法?
  • 请问为什麽在J2ee中客户端(测试时)用jndi定位enterprise bean的时候,可以把远程接口实例化?接口不是不可以生成对象的吗?
  • 大家说接口可以直接产生对象吗?
  • linux无线网络传输也可以直接使用socket接口编程吗?
  • linux下用什么命令可以查看网络接口的信息呢
  • 请教大家!!!java如何实现多重继承?接口该如何使用?份数可以再加,只要我明白了
  • 请问在RedHat7.1上可以用usb接口的easyDisk吗?
  • 虚拟机安装xampp后虚拟接口一访问网站,主机不可以
  • 菜鸟问题:Java可以用来开发驱动程序吗,或者说通讯、接口?或者说是否合适?
  • Collection,List都是接口,为什么我可以这么用?
  • 大家来讨论一下,在linux下除了openGL还有什么可以用于多媒体视频开发的接口库?
  • 一个多播的问题,是否可以指定特定的数据接收的接口?
  • 用java开发一个可以各种请求(包括手机短消息,邮件等等)的标准接口,各位指指路,来者有分
  • 一个类可以实现多个接口
  • android中可以通过两种方式调用接口发送短信
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 可以用文件控制访问吗?请分析如下原因,谢谢
  • windows下 有什么工具可以分析日志啊
  • shell脚本实现的网站日志分析统计(可以统计9种数据)
  • 请问gprof可以分析多进程的程序么
  • C++ MultiMaps 成员 max_size():返回可以容纳的最大元素个数
  • 我从网上下载LUNUX然后用盘刻录了可以安装吗?如果可以请告诉我下载地址可以吗?谢谢,我学习用的!谢谢
  • C++ Bitsets 成员 size():返回可以容纳的位的个数
  • tc下可以,gcc下不可以.请告说我,怎样就都可以了
  • C++ Maps 成员 max_size():返回可以容纳的最大元素个数
  • 生产者消费者问题为什么不可以共用一个信号量,如果这个信号量可以设置取值固定为0到N,即当信号量取值为N的时候阻塞进程,是否也可以?
  • 网站英文/中文域名字符集即网站英文/中文域名可以包含哪些字符
  • weblogic可不可以当作jndi服务器使用?如果可以,请问如何管理?
  • 必看!程序员升级之路,看了可以少走很多弯路
  • 请问用ftp可以不可以把整个目录一起上传。
  • linux可不可以和windows共享??可以的话,该怎么做?
  • 怎样写一个shell,可以查看一个文件的内容,并且有翻页的内容,并可以打印的
  • 可以从硬盘上安装redhat吗?linux可以用ghost备份吗?
  • 学习unix,急需教程,请问哪里可以下载,或者谁可以提供这方面的材料!
  • 在线等,为什么我的代码原来可以运行,现在不可以了????TextPad
  • 为什么在网页中有的applet可以显示,有的不可以显示 在线等待!!!!!
  • 有什么可以在2k server下可以用的分区工具?
  • iconv可以用来转换文字编码,有没有可以用来识别编码的?
  • 为什么我在linux7.1中有些命令有时可以用有时不可以用?
  • 怎样让一个.SH文件在任何目录下都可以直接敲入文件名*.SH就可以运行?
  • 我发现在Redhat Linux中有个选项可以连上MSN,不知怎么才可以连上,谢谢


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3