実際の回答は回答のコメントにあります。あなたがすることができない私のインターフェースの「インスタンス」を得ることを期待していました。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");
}
}
-
私はいくつかのコード生成をやってるとダイナミック型の多用を作っていますし、残念ながら私は、動的型/明示的なインターフェイスの難問を打ってきました。
hereのようにConvert.ChangeType(...)
を使用して回避することができますが、それは私がしたくないオーバーヘッドが大きいIConvertable
が実装されている必要があります。
私はExpression.TypeAs
またはExpression.Convert
のいずれかを使用してこれを行うには、LINQの式を使用してのfound an exampleが、しかし、これは常に基本となる具体的なタイプではなく、私は必要なインターフェイスを返してきました。
ここで私が何をしようとしているのコード例です:
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 ");を意味すると思いますが、実際にはここで問題は変わりません。動的オブジェクトをインタフェースに変換するための素晴らしいNugetである 'ImpromptuInterface'を使っても、このような明示的な実装にはまだアクセスできません。 –
BTW Convertメソッドは、パラメータを使用しないラムダボディを作成し、それをパラメータで呼び出す方法です。パラメータを作成し、定数値の代わりにTypeAsの最初のパラメータとして渡すか、Constantを引き続き使用して、lambdaパラメータとDynamicInvokeに渡されるパラメータを削除します。 (問題は変わらず、使い方を整えるだけです)。 –