C# 类型';T';与类型';T';

C# 类型';T';与类型';T';,c#,f#,office-interop,C#,F#,Office Interop,我有两个C语言编写的库,我想在F应用程序中使用。两个库使用相同的类型,但是,我无法说服F#的类型检查器这一事实 下面是一个使用Office互操作类型的简单示例。F#似乎对这些类型的问题特别敏感。从F#方面考虑似乎无助于解决这一问题。所有三个项目都引用同一程序集(“Microsoft.Office.Interop.Excel”14.0.0.0版) 在项目“项目1”(C#项目)中: 在项目“项目2”(一个C#项目)中: 在项目“TestApp”(一个F#项目)中: 然而,这并不令人满意,因为它是1)

我有两个C语言编写的库,我想在F应用程序中使用。两个库使用相同的类型,但是,我无法说服F#的类型检查器这一事实

下面是一个使用Office互操作类型的简单示例。F#似乎对这些类型的问题特别敏感。从F#方面考虑似乎无助于解决这一问题。所有三个项目都引用同一程序集(“Microsoft.Office.Interop.Excel”14.0.0.0版)

在项目“项目1”(C#项目)中:

在项目“项目2”(一个C#项目)中:

在项目“TestApp”(一个F#项目)中:


然而,这并不令人满意,因为它是1)动态的,2)我仍然不理解原始类型检查失败的原因。

COM interop。当您引用COM程序集时,它实际上会生成一个COM互操作程序集,以便在.NET和COM之间封送。如果有两个程序集都引用同一COM程序集,则实际上可能有两个相同生成的互操作程序集

一种解决方案,坦率地说是更好的设计,是在两个程序集(或共享的第三个程序集)中的一个程序集中创建接口,该程序集公开您想要公开的功能,而不是使用或消费COM类型,而是使用这些接口

namespace Project1
{
    public interface IApplication
    {
        // application members here...
    }

    public class Class1
    {
        public static IApplication GetApp()
        {
            return new ExcelApplication(new Microsoft.Office.Interop.Excel.Application());
        }

        private class ExcelApplication : IApplication
        {
            public ExcelApplication(Microsoft.Office.Interop.Excel.Application app)
            {
                 this.app = app;
            }

            // implement IApplication here...
        }
    }
}

我怀疑答案与F#编译器不理解无PIA类型的等价规则有关。+1 F#和C#在COM互操作中的工作方式略有不同,请参见:
namespace Project2
{
    public class Class2
    {
        Microsoft.Office.Interop.Excel.Application _app;

        public Class2(Microsoft.Office.Interop.Excel.Application app)
        {
            _app = app;
        }
    }
}
[<EntryPoint>]
let main argv = 
    let c2 = Project2.Class2(Project1.Class1.GetApp())
    0 
let c2 = Project2.Class2(Project1.Class1.GetApp() :?> Microsoft.Office.Interop.Excel.Application)
namespace Project1
{
    public interface IApplication
    {
        // application members here...
    }

    public class Class1
    {
        public static IApplication GetApp()
        {
            return new ExcelApplication(new Microsoft.Office.Interop.Excel.Application());
        }

        private class ExcelApplication : IApplication
        {
            public ExcelApplication(Microsoft.Office.Interop.Excel.Application app)
            {
                 this.app = app;
            }

            // implement IApplication here...
        }
    }
}