實際答案在答案的評論中。我期待得到我的界面的「實例」,這是你無法做到的。爲什麼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參數和參數。 (不會改變問題,只是清理使用)。 –