2

: new()型にパラメーターなしのコンストラクターがあるかどうかを確認して、それをキャストし、制約付きのパラメーターなしのコンストラクターを必要とするメソッドを呼び出すことはまったく可能ですか?

ターゲット メソッドの呼び出しが許可されないため、ここで回答されているように、タイプがパブリック パラメータなしであることを確認できるだけでは十分ではありません。

IInteresting目的は、オブジェクトが public パラメーターなしのコンストラクターを実装せず、 を呼び出す前に変換する必要がある、次のロジックを持つことSave1です。

    public interface IInteresting { }

    public void Save<T>(T o) {
        var oc = o as (new()); /* Pseudo implementation */
        if (oc != null) {
            this.Save1(oc);
        }
        else {
            var oi = o as IInteresting;
            if (oi != null) {
                this.Save2(oi);
            }
        }
    }

    private void Save1<T>(T o) where T : new() {
        //Stuff
    }

    private void Save2<T>(IInteresting o) {
        //Stuff to convert o to a DTO object with a public parameterless constructor, then call Save1(T o)
    }

もちろん、問題を解決する同じ署名を作成Save1してSave2共有できれば問題は解決しますが、次のコードはコンパイルされないため、その方法が見つかりません (ではRoutineSave2 番目の実装ではなく最初の実装が呼び出されます)。

    public void Routine<T>(T o) {
        var oi = o as IInteresting;
        if (oi != null) {
            this.Save(oi);
        }
    }

    private void Save<T>(T o) where T : new() {
        //Stuff
    }

    private void Save<T>(IInteresting o) {
        //Stuff to convert o to a DTO object with a public parameterless constructor, then call Save(T o)
    }
4

3 に答える 3

1

あなたのコメントに基づいて、渡されたオブジェクトがジェネリック型引数である必要があるジェネリック関数に渡したい未知の型のオブジェクトがあると思います。これには、パラメーターなしのコンストラクターが必要です。したがって、当分の間、Save1<T>(T)あなたの質問からのあなたの機能は、あなたが書いたものではなく、変更できない機能であると想定できます。

これに対する解決策は、リフレクションを使用して呼び出しを行うことです。

  • MethodInfoを使用して、呼び出そうとしているメソッドの を見つけますType.GetMethod
  • MethodInfoで型引数を指定して、parameterless-constructor-type のメソッドの を構築しますMakeGenericMethod
  • method を呼び出して、メソッドを呼び出しMethodInfo.Invokeます
于 2013-11-03T13:51:34.570 に答える
0
using System.Reflection;


public static class Generics {
 public static void T0<T> ( T obj ) where T : new () {
  Console.WriteLine ( "{0} {1}", obj, obj.GetType () );
 }

 public static void T1<T> ( T obj ) {
  MethodInfo mi = GenericMethodInfo ( typeof ( Generics ), "T0", typeof ( T ) );
  mi.Invoke ( null, new object[] { obj } );
 }

 public static MethodInfo GenericMethodInfo ( Type classType, string methodName, Type genericType ) {
  return classType.GetMethod ( methodName ).MakeGenericMethod ( genericType );
 }
}


Generics.T0 ( 123 );
Generics.T1 ( 123 );
// Impossible.. Generics.T0 ( "12345" );
Generics.T1 ( "12345" );
于 2014-09-26T16:39:17.257 に答える
0

内部で何をするかに応じて、別の可能な解決策は、インターフェイスprivate void Save<T>(T o) where T : new()を使用することです。ICloneableまたはあなたのものを紹介してください(私が言ったように、それはSaveのコンテンツに依存します):

interface IConstructible
{
    object Construct();
}

そして持っています:

private void Save1<T>(T o) where T : ICloneable {

もちろん、これは単なる回避策です-ORマッパーの答えは唯一の直接的な解決策を提供します。

于 2013-11-03T18:49:25.477 に答える