2

是否有可能检查一个类型是否具有无参数构造函数,以便对其进行强制转换并调用需要具有: new()约束的无参数构造函数的方法?

仅能够检查此处回答的公共无参数类型是不够的,因为它不允许调用目标方法。

目标是具有以下逻辑,其中IInteresting对象不实现公共无参数构造函数,需要在调用之前进行转换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)
    }

当然,如果我可以制作Save1Save2共享可以解决问题的相同签名,但我找不到这样做的方法,因为以下内容将无法编译(在 中RoutineSave将调用第一个实现而不是第二个实现):

    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)您的问题中的功能是该功能,不是您编写的,无法更改。

对此的解决方案是使用反射进行调用:

于 2013-11-03T13:51:34.570 回答
0

另一种可能的解决方案,取决于你在里面做什么,private void Save<T>(T o) where T : new()是使用ICloneableinterface. 或者介绍你的(正如我所说,这取决于Save's 的内容):

interface IConstructible
{
    object Construct();
}

并且有:

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

当然,这只是一种解决方法——或者 Mapper 的回答给出了唯一的直接解决方案。

于 2013-11-03T18:49:25.477 回答
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 回答