实际答案在答案的评论中。我期待得到我的界面的“实例”,这是你无法做到的。为什么Expression.TypeAs的评估返回基础具体类型的对象而不是我请求的接口?
-
I found a way to do what I actually wanted, which for anyone interested, I've outlined below.
public interface Interface<T> { Func<T,T> Property { get; set; } }
public class Concrete : Interface<string>
{
public Concrete()
{
(this as Interface<string>).Property = (s) => { return $"hello, {s}!"; };
}
Func<string, string> Interface<string>.Property
{
get;
set;
}
}
class Program
{
static void Main(string[] args)
{
object obj = new Concrete();
var propInfo = obj.GetType().GetInterfaces().Single().GetProperty("Property");
dynamic func = propInfo.GetMethod.Invoke(obj, null);
var output = func("world");
}
}
-
我做了一些代码生成和我大量使用动态类型的,不幸的是我已经打了动态式/显式接口难题。
我可以通过使用Convert.ChangeType(...)
来解决这个问题,如here所示,但是它需要IConvertable
被实现,这将会产生大量我不想做的事情。
我有found an example使用Linq表达式来使用Expression.TypeAs
或Expression.Convert
这样做,但是这总是返回底层的具体类型,而不是我需要的接口。
这里是我想要做的代码示例:
namespace ExpressionCasting
{
public interface Interface<T> { void Method(T t); }
public class ImplementedInterface : Interface<string>
{
void Interface<string>.Method(string t) { }
}
class Program
{
static void Main(string[] args)
{
var implementedInterface = new ImplementedInterface();
// type is an IInterface<string>
var type = implementedInterface.GetType().GetInterfaces().Single();
// i is always an ImplementedInterface
var i = Convert(type, implementedInterface); // i is always an ImplementedInterface
Console.WriteLine(i.GetType()); // i want this to be an IInterface<string> nit and ImplementedInterface.
}
static object Convert(Type type, object subClass)
{
var body = Expression.TypeAs(
Expression.Constant(subClass, subClass.GetType()), type);
var run = Expression.Lambda(
body, Expression.Parameter(subClass.GetType())).Compile();
return run.DynamicInvoke(subClass);
}
}
}
任何想法如何,我能得到什么,我需要用表情或如果我没有想到的另一种选择?
你的期望是不是很清楚 - 为什么得到实现接口类的实例是一个问题吗?你还期望什么结果 - 接口没有实例...另外,Mike [在回答中指出](http://stackoverflow.com/a/36894929/477420)'i.Method();'会总是抛出此方法不在界面中 - 确保您的示例实际显示了问题。 –
我认为你的意思是'i.Method(“foo”);'但这实际上并没有改变这里的问题。即使使用'ImpromptuInterface'这是一个很好的Nuget来将动态对象转换为接口,您仍然无法访问像这样的显式实现。 –
顺便说一下你的Convert方法创建一个不使用参数然后用参数调用的lambda体。创建一个参数并将其作为TypeAs的第一个参数而不是常量值传递,或者继续使用常量,并删除传递给DynamicInvoke的lambda参数和参数。 (不会改变问题,只是清理使用)。 –