summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/TypeLoadException.cs
blob: 5e748a6c58fe4a133216e6d706fe07f07481ab88 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

/*=============================================================================
**
**
**
** Purpose: The exception class for type loading failures.
**
**
=============================================================================*/

using System;
using System.Globalization;
using System.Runtime.Serialization;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Diagnostics.Contracts;

namespace System
{
    public class TypeLoadException : SystemException, ISerializable
    {
        public TypeLoadException()
            : base(SR.Arg_TypeLoadException)
        {
            HResult = __HResults.COR_E_TYPELOAD;
        }

        public TypeLoadException(String message)
            : base(message)
        {
            HResult = __HResults.COR_E_TYPELOAD;
        }

        public TypeLoadException(String message, Exception inner)
            : base(message, inner)
        {
            HResult = __HResults.COR_E_TYPELOAD;
        }

        public override String Message
        {
            get
            {
                SetMessageField();
                return _message;
            }
        }

        private void SetMessageField()
        {
            if (_message == null)
            {
                if ((ClassName == null) &&
                    (ResourceId == 0))
                    _message = SR.Arg_TypeLoadException;

                else
                {
                    if (AssemblyName == null)
                        AssemblyName = SR.IO_UnknownFileName;
                    if (ClassName == null)
                        ClassName = SR.IO_UnknownFileName;

                    String format = null;
                    GetTypeLoadExceptionMessage(ResourceId, JitHelpers.GetStringHandleOnStack(ref format));
                    _message = String.Format(CultureInfo.CurrentCulture, format, ClassName, AssemblyName, MessageArg);
                }
            }
        }

        public String TypeName
        {
            get
            {
                if (ClassName == null)
                    return String.Empty;

                return ClassName;
            }
        }

        // This is called from inside the EE. 
        private TypeLoadException(String className,
                                  String assemblyName,
                                  String messageArg,
                                  int resourceId)
        : base(null)
        {
            HResult = __HResults.COR_E_TYPELOAD;
            ClassName = className;
            AssemblyName = assemblyName;
            MessageArg = messageArg;
            ResourceId = resourceId;

            // Set the _message field eagerly; debuggers look at this field to 
            // display error info. They don't call the Message property.
            SetMessageField();
        }

        protected TypeLoadException(SerializationInfo info, StreamingContext context) : base(info, context)
        {
            throw new PlatformNotSupportedException();
        }

        [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
        [SuppressUnmanagedCodeSecurity]
        private static extern void GetTypeLoadExceptionMessage(int resourceId, StringHandleOnStack retString);

        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            base.GetObjectData(info, context);
        }

        // If ClassName != null, GetMessage will construct on the fly using it
        // and ResourceId (mscorrc.dll). This allows customization of the
        // class name format depending on the language environment.
        private String ClassName;
        private String AssemblyName;
        private String MessageArg;
        internal int ResourceId;
    }
}