Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# (ab)使用CoClassAttribute为接口提供默认实现可以吗?_C#_.net_Com_Api Design_Coclass - Fatal编程技术网

C# (ab)使用CoClassAttribute为接口提供默认实现可以吗?

C# (ab)使用CoClassAttribute为接口提供默认实现可以吗?,c#,.net,com,api-design,coclass,C#,.net,Com,Api Design,Coclass,我最近发现,可以通过用修饰接口来指定默认实现 [ComImport, Guid("579A4F68-4E51-479A-A7AA-A4DDC4031F3F"), CoClass(typeof(FooImpl))] public interface IFoo { void Bar(); } public class FooImpl : IFoo { public void Bar() { } } ... // Constructs a FooImpl IFoo foo = n

我最近发现,可以通过用修饰接口来指定默认实现

[ComImport, Guid("579A4F68-4E51-479A-A7AA-A4DDC4031F3F"), CoClass(typeof(FooImpl))]
public interface IFoo
{
    void Bar();
}

public class FooImpl : IFoo
{
    public void Bar() { }
}

...

// Constructs a FooImpl
IFoo foo = new IFoo();
我知道这个特性的存在主要是为了支持COM互操作,但我想知道这是否是将接口与泛型类库中的默认实现相关联的合理方法

我有两个问题:

  • 这样做有什么困难吗?我不是COM互操作方面的专家,我不知道这是否会对POCOs产生任何负面影响。我没有运行任何主要的测试,但我的示例中的IL似乎还可以(在
    FooImpl
    上的正常
    newobj
    指令,而不是调用
    Type.GetTypeFromCLSID
    Activator.CreateInstance

  • 即使这样做可以顺利进行,是否还有其他原因(比如从API设计的角度)可以避免这种情况


  • 使用IntelliSense评论:

        /// <summary>
        /// Explain here all about interface
        /// </summary>
    
    //
    ///在这里解释所有关于接口的内容
    /// 
    
    而不是对属性进行黑客攻击,因为这可能会在使用您的类的其他人的半反射实现中适得其反。属性将由使用反射的工具使用,IntelisSense用于文档

    [ComImport, Guid("579A4F68-4E51-479A-A7AA-A4DDC4031F3F"), CoClass(typeof(FooImpl))]
    public interface IFoo
    {
        void Bar();
    }
    
    public class FooImpl : IFoo
    {
        public void Bar() { }
    }
    
    ...
    
    // Constructs a FooImpl
    IFoo foo = new IFoo();
    

    诚然,某些旧工具在读取///注释时会遇到问题,但它们也无法读取您的属性。

    您不应该这样做的关键原因是您正在对不需要COM生命周期管理的对象实例启动COM生命周期管理。NET现在必须进行一些COM互操作,包括安全堆栈遍历、单元线程检查和addref/release等

    相反,我会考虑依赖注入(反转控制模式)和公共服务定位器模式。我将重点理解构造函数注入,因为它是依赖关系管理的首选模式

    以下是我在图书馆里做的事情。假设我想写一个日志服务(人为的例子)。我将有两个核心部分:

    MyStuff.Logging.Contracts-这里是我声明ILogger接口的地方 Logging-在这里我将编写不同的日志实现,比如FileLogger、DatabaseLogger等


    然后在我的应用程序中,我会使用Ninject或Unity(DI容器)将ILogger与默认实现相关联。

    mono实现的代码可能已被破坏,因为您使用的是windows特定的东西。我可以通过关闭的门听到WTF的密集声,这应该是足够的理由。你最好描述一下。这真的完成了工厂做不到的事情吗?谢谢。即使在纯.NET环境中,运行时真的会因为这些属性的存在而完成所有这些工作吗?你能给我提供一些关于这个的信息吗?看看这个:。“ComImportAttribute是一个伪自定义属性,表示已在以前发布的类型库中定义了一个类型。公共语言运行库在激活、导出、强制等操作时会对这些类型进行不同的处理。”而使用新运算符可能只会调用构造函数。我认为运行时必须进行生命周期管理和线程单元管理,否则该类实际上不是COM对象。这个问题不是关于注释,而是接口的默认实现。很好,否决一个相互竞争的答案总是好的,但我感谢你没有匿名这么做。无论如何,问题是。“这样做有什么困难吗?”我回答了这个问题,并提出了一个正确的方法来解决他的问题。。。
    [ComImport, Guid("579A4F68-4E51-479A-A7AA-A4DDC4031F3F"), CoClass(typeof(FooImpl))]
    public interface IFoo
    {
        void Bar();
    }
    
    public class FooImpl : IFoo
    {
        public void Bar() { }
    }
    
    ...
    
    // Constructs a FooImpl
    IFoo foo = new IFoo();