使用内部构造函数创建泛型类

发布于 2024-09-17 20:23:56 字数 732 浏览 8 评论 0原文

是否可以在泛型方法中使用其内部构造函数构造一个对象?

public abstract class FooBase { }

public class Foo : FooBase {
   internal Foo() { }
}

public static class FooFactory {
    public static TFooResult CreateFoo<TFooResult>()
    where TFooResult : FooBase, new() {
        return new TFooResult();
    }
}

FooFactoryFoo 驻留在同一程序集中。类像这样调用工厂方法:

var foo = FooFactory.CreateFoo<Foo>();

它们得到编译时错误:

“Foo”必须是具有公共无参数构造函数的非抽象类型,才能将其用作泛型类型或方法“FooFactory.CreateFoo()”中的参数“TFooType”

有没有办法解决这个问题?

我也尝试过:

Activator.CreateInstance<TFooResult>(); 

这会在运行时引发相同的错误。

Is it possible to construct an object with its internal constructor within a generic method?

public abstract class FooBase { }

public class Foo : FooBase {
   internal Foo() { }
}

public static class FooFactory {
    public static TFooResult CreateFoo<TFooResult>()
    where TFooResult : FooBase, new() {
        return new TFooResult();
    }
}

FooFactory resides in the same assembly as Foo. Classes call the factory method like this:

var foo = FooFactory.CreateFoo<Foo>();

They get the compile-time error:

'Foo' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'TFooType' in the generic type or method 'FooFactory.CreateFoo()'

Is there any way to get around this?

I also tried:

Activator.CreateInstance<TFooResult>(); 

This raises the same error at runtime.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

枫林﹌晚霞¤ 2024-09-24 20:23:56

您可以删除 new() 约束并返回:

//uses overload with non-public set to true
(TFooResult) Activator.CreateInstance(typeof(TFooResult), true); 

尽管客户端也可以这样做。然而,这很容易出现运行时错误。

这是一个很难以安全方式解决的问题,因为该语言不允许抽象构造函数声明。

You could remove the new() constraint and return:

//uses overload with non-public set to true
(TFooResult) Activator.CreateInstance(typeof(TFooResult), true); 

although the client could do that too. This, however, is prone to runtime errors.

This is a hard problem to solve in a safe manner since the language does not permit an abstract constructor declaraton.

柠檬心 2024-09-24 20:23:56

类型参数必须有一个
公共无参数构造函数。与其他产品一起使用时
约束,new() 约束必须
最后指定。

http://msdn.microsoft.com/en-us/library/d5x73970。 aspx

编辑:所以不,如果您使用 new() 约束,则无法传递该类,如果您不使用 new() 约束,您可以尝试使用反射来创建新实例

public static TFooResult CreateFoo<TFooResult>()
where TFooResult : FooBase//, new()
        {
            return (TFooResult)typeof(TFooResult).GetConstructor(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance, null, new Type[] {}, null).Invoke(new object[]{});
            //return new TFooResult();
        }

The type argument must have a
public parameterless constructor. When used together with other
constraints, the new() constraint must
be specified last.

http://msdn.microsoft.com/en-us/library/d5x73970.aspx

edit: so no, if you use new() constraint, you cannot pass that class, if you don't use new() constraint you can try using reflection to create new instance

public static TFooResult CreateFoo<TFooResult>()
where TFooResult : FooBase//, new()
        {
            return (TFooResult)typeof(TFooResult).GetConstructor(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance, null, new Type[] {}, null).Invoke(new object[]{});
            //return new TFooResult();
        }
被翻牌 2024-09-24 20:23:56

可能有以下几种解决方法,但我认为您不想这样做!

  • 将 switch 语句放入 Factory 中
    这将创建基于实例
    on type 参数的类型。

  • FooBase 的每个具体实现都会向 FooFactory 注册,并传递工厂方法来创建它自己。因此 FooFactory 将使用内部字典

  • 在类似的行上扩展,除了类型参数和具体实现之间的映射将是外部代码(xml 文件、配置等)。 IOC/DI 容器也可以在这里提供帮助。

There can be few work-arounds as below but I don't think you want to go that way!

  • Put switch statement inside Factory
    that will create the instance based
    on type of type parameter.

  • Each concrete implementation of FooBase will register with FooFactory passing the factory method to create it self. So FooFactory will use the internal dictionary

  • Extending on the similar line except mapping between type parameter and concrete implementation would be external code (xml file, configuration etc). IOC/DI containers can also help here.

时光磨忆 2024-09-24 20:23:56
public class GenericFactory
{
    public static T Create<T>(object[] args)
    {
        var types = new Type[args.Length];
        for (var i = 0; i < args.Length; i++)
            types[i] = args[i].GetType();

        return (T)typeof(T).GetConstructor(types).Invoke(args);
    }
}
public class GenericFactory
{
    public static T Create<T>(object[] args)
    {
        var types = new Type[args.Length];
        for (var i = 0; i < args.Length; i++)
            types[i] = args[i].GetType();

        return (T)typeof(T).GetConstructor(types).Invoke(args);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文