TypeAccessException是一种.NET平台下的异常类型,表示访问了不被许可的成员或类型。一些常见的原因是访问了私有(private),受保护(protected)或内部(internal)成员,或者访问了另一个程序集中标记为internal的成员。下面详细讲解TypeAccessException的原因以及解决办法,并提供两个示例。
一、TypeAccessException的原因
TypeAccessException通常由以下原因引起:
-
访问私有类型成员:TypeAccessException会在试图访问非公共类型的私有成员时抛出。访问过程中可能会使用反射API获取或设置私有成员。
-
访问非公共类型:TypeAccessException还可能在试图实例化非公共类型、访问非公共类型成员或调用非公共类型成员等情况下抛出。
-
访问internal类型成员:TypeAccessException也可能在试图从另一个程序集中访问(例如,使用反射API)标记为internal的类型成员时抛出。
二、TypeAccessException的解决办法
解决TypeAccessException,需要做的主要有以下两个方面:
- 修改访问修饰符:如果试图访问的类型或成员的访问修饰符为private、protected或internal,需要修改访问修饰符为public或internal。
示例一:在访问私有成员时抛出TypeAccessException
class MyClass
{
private string privateField = "Hello World!";
}
class Program
{
static void Main(string[] args)
{
var instance = new MyClass();
// 使用反射API获取私有成员时抛出异常
var privateFieldValue = instance.GetType()
.GetField("privateField", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(instance);
}
}
解决方法:将privateField修改为public或internal
class MyClass
{
public string privateField = "Hello World!";
}
class Program
{
static void Main(string[] args)
{
var instance = new MyClass();
// 不会抛出TypeAccessException
var privateFieldValue = instance.privateField;
}
}
示例二:在访问internal成员时抛出TypeAccessException
// 程序集A
[assembly: InternalsVisibleTo("AssemblyB")] // 允许程序集B访问程序集A中的internal成员
class MyClass
{
internal string internalField = "Hello World!";
}
// 程序集B
class Program
{
static void Main(string[] args)
{
var instance = new MyClass();
// 试图通过反射API访问internalField时抛出TypeAccessException
var internalFieldValue = instance.GetType()
.GetField("internalField", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(instance);
}
}
解决方法:在程序集B中添加程序集A的InternalsVisibleTo属性,允许程序集B访问程序集A中标记为internal的成员。
[assembly: InternalsVisibleTo("AssemblyB")]
class MyClass
{
internal string internalField = "Hello World!";
}
class Program
{
static void Main(string[] args)
{
var instance = new MyClass();
// 不会抛出TypeAccessException
var internalFieldValue = instance.internalField;
}
}
- 使用公共类型或成员:如果试图访问的类型或成员是public的,则可以正常访问。
示例三:访问公共类型或成员时不会抛出TypeAccessException
class MyClass
{
public string publicField = "Hello World!";
}
class Program
{
static void Main(string[] args)
{
var instance = new MyClass();
// 不会抛出TypeAccessException
var publicFieldValue = instance.publicField;
}
}
综上,要解决TypeAccessException异常,需要对访问的类型或成员的访问修饰符进行修改,或使用公共类型或成员。