C# 同一程序集不同版本中相同类型的类型转换

C# 同一程序集不同版本中相同类型的类型转换,c#,.net,casting,types,C#,.net,Casting,Types,我遇到了一个问题,我不确定我是否能回避。我的库和另一个库都为特定类型的数据提供了API,我现在已经编写了一个互操作库,它可以位于两个库之间,并在它们之间自由转换数据,这非常有效 但我现在尝试编写一个小的演示应用程序,使用依赖于另一个API的第三个库通过我的API访问数据,下面是我遇到的问题。第三个库引用了另一个API的合并版本和一些相关的DLL,这些DLL要引导的是另一个API的旧版本,而我的API引用了另一个API的独立形式的最新版本。所以首先,我必须使用一个外部别名来编写包含3个库的代码,否

我遇到了一个问题,我不确定我是否能回避。我的库和另一个库都为特定类型的数据提供了API,我现在已经编写了一个互操作库,它可以位于两个库之间,并在它们之间自由转换数据,这非常有效

但我现在尝试编写一个小的演示应用程序,使用依赖于另一个API的第三个库通过我的API访问数据,下面是我遇到的问题。第三个库引用了另一个API的合并版本和一些相关的DLL,这些DLL要引导的是另一个API的旧版本,而我的API引用了另一个API的独立形式的最新版本。所以首先,我必须使用一个外部别名来编写包含3个库的代码,否则类型冲突,它将无法编译

因此,现在当我尝试编写一个应用程序,从我的API获取数据,通过互操作层运行它,将其转换为另一个API,然后在此数据上使用第三个库时,会出现问题,因为.Net不会在类型之间转换,因为它认为这些类型不同。有没有办法强迫.Net这么做,还是我运气不好

据我所知,第三个库的作者计划在将来将其库移动到基于另一个API的最新版本(1.0.6.4),所以我可能不得不等到那时

using System;
using System.Collections.Generic;
using System.Linq;
using VDS.RDF;
using VDS.RDF.Interop;
using VDS.RDF.Parsing;
using VDS.RDF.Storage;
using SemWeb;
using LinqToRdf;

namespace RdfMusic
{
    public class Program
    {
        public static void Main(string[] args)
        {
            try
            {
                //Get the Talis Connection
                TalisPlatformConnector talis = new TalisPlatformConnector("store", "user", "password");
                NativeStoreSource source = new NativeStoreSource(talis);

                //Load the Data
                Graph g = new Graph();
                FileLoader.Load(g, "data.ttl");

                //Ensure the data is in Talis
                talis.SaveGraph(g);

                //Now do a LinqToRdf query
                //BUG: This cast fails since it's trying to cast to StatementSource in 
                //the SemWeb library (version 1.0.5.0 as referenced by LinqToRdf) from
                //a StatementSource in the SemWeb library (version 1.0.6.4 as referenced by dotNetRDF)
                StatementSource stmtSource = (StatementSource)source;
                LinqToRdf.TripleStore ts = new LinqToRdf.TripleStore(new Store(stmtSource));
                ts.QueryType = QueryType.LocalN3StoreInMemory;

                IEnumerable<Track> tracks = from t in new MusicDataContext(ts).ForType<Track>()
                                            where t.Year == "2006"
                                            select t;

                foreach (Track t in tracks)
                {
                    Console.Write(t.Title + " by " + t.ArtistName);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
                Exception innerEx = ex.InnerException;
                while (innerEx != null)
                {
                    Console.WriteLine();
                    Console.WriteLine(innerEx.Message);
                    Console.WriteLine(innerEx.StackTrace);
                    innerEx = innerEx.InnerException;
                }
            }

            Console.WriteLine();
            Console.WriteLine("Press Enter to exit");
            Console.ReadLine();
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用VDS.RDF;
使用VDS.RDF.Interop;
使用VDS.RDF.Parsing;
使用VDS.RDF.Storage;
使用SemWeb;
使用LinqToRdf;
名称空间RdfMusic
{
公共课程
{
公共静态void Main(字符串[]args)
{
尝试
{
//获取Talis连接
TalisPlatformConnector talis=新的TalisPlatformConnector(“存储”、“用户”、“密码”);
NativeStoreSource=新的NativeStoreSource(talis);
//加载数据
图g=新图();
Load(g,“data.ttl”);
//确保数据在Talis中
图(g);
//现在执行LinqToRdf查询
//错误:此强制转换失败,因为它试图在中强制转换到StatementSource
//来自的SemWeb库(LinqToRdf引用的版本1.0.5.0)
//SemWeb库中的语句Source(dotNetRDF引用的版本1.0.6.4)
StatementSource stmtSource=(StatementSource)源;
LinqToRdf.TripleStore ts=新的LinqToRdf.TripleStore(新存储(stmtSource));
ts.QueryType=QueryType.LocalN3StoreInMemory;
IEnumerable tracks=在新的MusicDataContext(ts).ForType()中从t开始
其中t.Year==“2006”
选择t;
foreach(轨道中的t轨道)
{
控制台。写入(t.Title+“by”+t.ArtistName);
}
}
捕获(例外情况除外)
{
控制台写入线(例如消息);
控制台写入线(例如StackTrace);
异常innerEx=ex.InnerException;
while(innerEx!=null)
{
Console.WriteLine();
Console.WriteLine(innerEx.Message);
Console.WriteLine(innerEx.StackTrace);
innerEx=innerEx.InnerException;
}
}
Console.WriteLine();
控制台写入线(“按回车键退出”);
Console.ReadLine();
}
}
}

是的,你运气不好。从CLR的角度来看,类型名称是程序集名称+可选模块名称+类型名称(这包括名称空间和外部类),系统是标称的,而不是结构化的-不同的名称意味着不同的类型。您所能做的最好是手动转换,只要您能够提供成员的可访问性(或者只是使用反射解决问题)。

是的,您运气不好。从CLR的角度来看,类型名称是程序集名称+可选模块名称+类型名称(这包括名称空间和外部类),系统是标称的,而不是结构化的-不同的名称意味着不同的类型。在给定成员的可访问性的情况下,您最好手动转换(或者使用反射解决问题)。

在这种情况下,您可以使用来简化类型之间的映射。

在这种情况下,您可以使用来简化类型之间的映射。

的确如此。但是请注意,C#4将支持接口上有限形式的结构类型。有关详细信息,请参见。@Eric,我已经尝试过了,但从我所看到的情况来看,要让C编译器使用它确实很困难-只是粘贴
TypeIdentifierAttribute
并没有剪切它,它还需要一组COM互操作属性(它们看起来就像是试图确保程序集是主互操作程序集)。这是在VS2010测试版2中,虽然…确实如此。但是请注意,C#4将支持接口上有限形式的结构类型。有关详细信息,请参见。@Eric,我已经尝试过了,但从我所看到的情况来看,要让C编译器使用它确实很困难-只是粘贴
TypeIdentifierAttribute
并没有剪切它,它还需要一组COM互操作属性(它们看起来就像是试图确保程序集是主互操作程序集)。这是在VS2010测试版2中,不过。。。