预期:
调用通用方法_client.Read,该方法返回ReadEvent,并且ReadEvent具有属性T值。(有关_client.Read的更多详细信息,请参阅PS)
我成功使用MakeGenericMethod
调用了泛型方法,但是我不知道如何在ReadEvent<T>
中获取Value。
public T Read<T>(ItemId itemId)
{
var type = Type.GetType(itemId.NameOfType);
ReadEvent<type> readEvent = _client.Read<type>(itemId.Tag);
return (T) readEvent.Value;
}
示例:
string result = Read<string>(itemWithBoolValue);
// itemWithBoolValue.NameOfType == "System.Boolean"
尝试:
readEvent
是对象,我不知道如何使用正确的T将其转换为ReadEvent<T>
。
public T Read<T>(ItemId itemId)
{
var type = Type.GetType(itemId.NameOfType);
var methodInfo = typeof(DaClient).GetMethod("Read");
var generic = methodInfo.MakeGenericMethod(type);
object readEvent = generic.Invoke(_client, new object[] { itemId.Tag });
var propertyInfo = typeof(ReadEvent<>).GetProperty("Value");
// System.InvalidOperationException: Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.
var value = propertyInfo.GetValue(readEvent);
return (T)value;
}
PS:DaClient Read的源代码
class DaClient;
{
public ReadEvent<T> Read<T>(string tag)
{
var item = new OpcDa.Item { ItemName = tag };
if (Status == OpcStatus.NotConnected)
{
throw new OpcException("Server not connected. Cannot read tag.");
}
var result = _server.Read(new[] { item })[0];
T casted;
TryCastResult(result.Value, out casted);
var readEvent = new ReadEvent<T>();
readEvent.Value = casted;
readEvent.SourceTimestamp = result.Timestamp;
readEvent.ServerTimestamp = result.Timestamp;
if (result.Quality == OpcDa.Quality.Good) readEvent.Quality = Quality.Good;
if (result.Quality == OpcDa.Quality.Bad) readEvent.Quality = Quality.Bad;
return readEvent;
}
...
}
答案 0 :(得分:0)
如果用动态替换对象readEvent怎么办,因此可以轻松访问value属性并将其强制转换为T:
public T Read<T>(ItemId itemId)
{
var type = Type.GetType(itemId.NameOfType);
var methodInfo = typeof(DaClient).GetMethod("Read");
var generic = methodInfo.MakeGenericMethod(type);
dynamic readEvent = generic.Invoke(_client, new object[] { itemId.Tag });
var value = readEvent.Value;
return (T)value;
}