Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.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# try/catch未捕获TypeLoadException_C#_Type Safety_Typeloadexception - Fatal编程技术网

C# try/catch未捕获TypeLoadException

C# try/catch未捕获TypeLoadException,c#,type-safety,typeloadexception,C#,Type Safety,Typeloadexception,为了演示,我试图重新创建一个TypeLoadException,所以我有一个可笑的库设置,看起来像这样: TestProject --> TheLibrary [1.0] \-> ProxyForV2 -> TheLibrary [2.0] 图书馆版本1具有以下相关接口: public interface IConsistentThing { int ConsistentProperty { get; set; } } public inte

为了演示,我试图重新创建一个
TypeLoadException
,所以我有一个可笑的库设置,看起来像这样:

TestProject --> TheLibrary [1.0]
            \-> ProxyForV2 -> TheLibrary [2.0]
图书馆
版本1具有以下相关接口:

public interface IConsistentThing
{
    int ConsistentProperty { get; set; }
}

public interface IShrinkingThing
{
    int RemovedProperty { get; set; }
}
库的第2版的接口如下所示:

public interface IConsistentThing
{
    int ConsistentProperty { get; set; }
}

public interface IShrinkingThing
{ }
ProxyForV2
有一个类,它实现了2.0版
IShringThing

public class ShrinkingThingImpl : IShrinkingThing
{
    public int ConsistentProperty { get; set; }
}
因此,在
TestProject
中,如果有人试图为v2.ShrinkingThingImpl分配
ProxyForV2.ShrinkingThingImpl
,我希望会导致
TypeLoadException
,因为接口的第一个版本具有第二个版本未实现的属性。为了证明这一点,我做了一个单元测试,如下所示:

[TestMethod]
public void ShrinkingThingBreaks()
{
    try
    {
        IShrinkingThing thing = new ProxyForV2.ShrinkingThingImpl();

        Assert.Fail("This should have caused a TypeLoadException");
    }
    catch (TypeLoadException)
    {
        //  valid
    }
}
我的问题是:这个单元测试失败了。但这并不是由于我的
Assert.Fail
,正如我所期望的那样。测试输出如下所示:

TestProject --> TheLibrary [1.0]
            \-> ProxyForV2 -> TheLibrary [2.0]
测试方法TestProject.LoadTester.ShrinkingThingBreaks引发异常:System.TypeLoadException:程序集“ProxyForV2,版本=1.0.0.0,区域性=中性,PublicKeyToken=null”中类型为“ProxyForV2.ShrinkingThingImpl”的方法“get\u RemovedProperty”没有实现

因此,正在抛出一个
TypeLoadException
,尽管它唯一可能被抛出的位置是在带有
catch(TypeLoadException)
try
块中,但异常拒绝被捕获。除此之外,即使我使用了一个catch all,单元测试也会失败,错误与之前相同:

[TestMethod]
public void ShrinkingThingBreaks()
{
    try
    {
        IShrinkingThing thing = new ProxyForV2.ShrinkingThingImpl();

        Assert.Fail("This should have caused a TypeLoadException");
    }
    catch
    {
        //  valid
    }
}
发生了什么事?显然,这是一个完全人为设计的场景,但我仍然想知道发生了什么,以便在运行时避免这个错误,或者至少在发生错误时处理它(是的,我知道最终的解决方案是确保所有库版本都相同)

最糟糕的是,对该类的任何访问,例如
typeof(ProxyForV2.ConsistentThingImpl)
ProxyForV2.ConsistentThingImpl.SomeStaticFunction()
都会导致此不可捕获的
TypeLoadException
,因此很明显,当.NET尝试加载该类时会产生问题,不是因为任何任务

我缓解这个问题的唯一想法是尝试在不同的应用程序域中加载类型,这样它就不会干扰,然后做一些疯狂的反射工作,看看接口是否与实现兼容,但这似乎是完全的、完全的过火了


总而言之:为什么用“正常”的方式似乎不可能捕捉到这个问题?我如何在运行时解决这样的问题?

类型在使用它们的方法开始执行之前被加载。为此,您需要:

[TestMethod]
public void ShrinkingThingBreaks()
{
    try
    {
        InnerShrinkingThingBreaks();

        Assert.Fail("This should have caused a TypeLoadException");
    }
    catch
    {
        //  valid
    }
}

[MethodImpl(MethodImplAttributes.NoInlining)]
private void InnerShrinkingThingBreaks()
{
        IShrinkingThing thing = new ProxyForV2.ShrinkingThingImpl();
}

对此不完全确定,所以只发表评论。。。单元测试的类型不都是预先加载的吗?因此,TypeLoadException实际上是在您到达try/catch块之前抛出的。我不知道你怎么能测试这个…在这个类中还有其他的单元测试通过得很好。如果您的意思是在方法调用时加载方法中使用的类型,那么这可能是issue.Works的根源。它也可以通过对lambda函数执行相同的操作来工作。@TravisGockel有没有使用lamda函数的示例?@Kiquenet:因为已经4年了,我记不清了,但我认为在
try
块中,我说了这样的话:
Action f=delegate(){var x=new ProxyForV2.ShrinkingThingImpl();};f()@TravisGockel关于lamba函数的绝妙提示!它可以让你实现一个内联解决方案;这解释了为什么我的静态构造函数会抛出异常,尽管我用try-catch包住了其中的所有内容!我知道在静态构造函数中执行太多操作是不好的,现在我有了一个额外的理由来避免在这种情况下进行“复杂”的初始化。。。