Я совершенно уверен, что мне не хватает какого-то ограничения или где-то здесь, но здесь моя ситуация. Предположим, у меня есть класс, для которого я хочу иметь прокси-сервер, например:
public class MyList : MarshalByRefObject, IList<string>
{
private List<string> innerList;
public MyList(IEnumerable<string> stringList)
{
this.innerList = new List<string>(stringList);
}
// IList<string> implementation omitted for brevity.
// For the sake of this exercise, assume each method
// implementation merely passes through to the associated
// method on the innerList member variable.
}
Я хочу создать прокси для этого класса, чтобы я мог перехватывать вызовы методов и выполнять некоторую обработку на базовом объекте. Вот моя реализация:
public class MyListProxy : RealProxy
{
private MyList actualList;
private MyListProxy(Type typeToProxy, IEnumerable<string> stringList)
: base(typeToProxy)
{
this.actualList = new MyList(stringList);
}
public static object CreateProxy(IEnumerable<string> stringList)
{
MyListProxy listProxy = new MyListProxy(typeof(MyList), stringList);
object foo = listProxy.GetTransparentProxy();
return foo;
}
public override IMessage Invoke(IMessage msg)
{
IMethodCallMessage callMsg = msg as IMethodCallMessage;
MethodInfo proxiedMethod = callMsg.MethodBase as MethodInfo;
return new ReturnMessage(proxiedMethod.Invoke(actualList, callMsg.Args), null, 0, callMsg.LogicalCallContext, callMsg);
}
}
Наконец, у меня есть класс, который использует прокси-класс, и я устанавливаю значение элемента MyList
через отражение.
public class ListConsumer
{
public MyList MyList { get; protected set; }
public ListConsumer()
{
object listProxy = MyListProxy.CreateProxy(new List<string>() { "foo", "bar", "baz", "qux" });
PropertyInfo myListPropInfo = this.GetType().GetProperty("MyList");
myListPropInfo.SetValue(this, listProxy);
}
}
Теперь, если я попытаюсь использовать отражение для доступа к прокси-объекту, у меня возникают проблемы. Вот пример:
class Program
{
static void Main(string[] args)
{
ListConsumer listConsumer = new ListConsumer();
// These calls merely illustrate that the property can be
// properly accessed and methods called through the created
// proxy without issue.
Console.WriteLine("List contains {0} items", listConsumer.MyList.Count);
Console.WriteLine("List contents:");
foreach(string stringValue in listConsumer.MyList)
{
Console.WriteLine(stringValue);
}
Type listType = listConsumer.MyList.GetType();
foreach (Type interfaceType in listType.GetInterfaces())
{
if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(ICollection<>))
{
// Attempting to get the value of the Count property via
// reflection throws an exception.
Console.WriteLine("Checking interface {0}", interfaceType.Name);
System.Reflection.PropertyInfo propInfo = interfaceType.GetProperty("Count");
int count = (int)propInfo.GetValue(listConsumer.MyList, null);
}
else
{
Console.WriteLine("Skipping interface {0}", interfaceType.Name);
}
}
Console.ReadLine();
}
}
Попытка вызвать GetValue
в свойстве Count
через отражение вызывает следующее исключение:
Исключение типа 'System.Reflection.TargetException' произошло в mscorlib.dll, но не был обработан в коде пользователя
Дополнительная информация: Объект не соответствует типу цели.
При попытке получить значение свойства Count
, видимо, структура обращается к System.Runtime.InteropServices.WindowsRuntime.IVector
, чтобы вызвать метод get_Size
. Я не понимаю, как этот вызов терпит неудачу в базовом объекте прокси (фактический список), чтобы это произошло. Если я не использую прокси-объект объекта, получение значения свойства отлично работает через отражение. Что я делаю не так? Могу ли я сделать то, что я пытаюсь выполнить?
Изменить: Открыта ошибка относительно этой проблемы на сайте Microsoft Connect.