【问题标题】:Namespace constraint with generic class declaration具有泛型类声明的命名空间约束
【发布时间】:2010-06-13 13:43:04
【问题描述】:

我想知道是否(以及如何)可以将命名空间定义为泛型类声明中的约束参数。

我拥有的是这样的:

namespaceMyProject.Models.Entities

namespaceMyProject.Tests.BaseTest

现在我的“BaseTest”类的声明看起来像这样;

public class BaseTest<T>

这个BaseTest 所做的(在撰写本文时)只不过是删除了在测试期间添加到数据库中的所有实体。所以通常我会有一个测试类声明为:

public class MyEntityRepositoryTest : BaseTest<MyEntity>

我想做的是类似于以下内容:

public class BaseTest<T> where T : <is of the MyProject.Models.Entities namespace>

现在我知道,完全可以简单地声明一个“BaseEntity”类,在 MyProject.Models.Entities 命名空间中创建的所有实体都将从该类继承;

public class BaseTest<T> where T : MyBaseEntity

但是...我实际上不需要或不想。另外,我正在使用 ORM 并映射实体与继承,虽然可能,但增加了一层不必要的复杂性。

那么,是否可以将泛型类参数约束到命名空间而不是特定类型?

【问题讨论】:

    标签: c# generics parameters constraints


    【解决方案1】:

    不可能为命名空间创建任何此类约束。

    更可取的解决方法是使您的泛型类internal 而不是public。这意味着类只能直接被同一程序集中的类实例化和访问(除非您使用InternalsVisibleTo 属性)。但是,它仍然可以间接实例化(即作为公共类的受保护/私有成员)。

    【讨论】:

    • 同意。而且,如果您要允许的类型在不同的程序集中,请查看InternalsVisibleToAttribute。我经常在不同的程序集中将它与单元测试一起使用。
    • 真遗憾,我很惊讶你不能用 lambda 表达式或其他东西做某事。不用担心,“内部”解决方案可以满足我的一半需求。感谢您的指导。
    • @SomeGuy,据我所知,lambdas 仍然只是运行时的东西(除了与表达式一起使用时,但即使那样它们在编译时也不能执行)。关于未来的 C# 5.0 编译器即服务功能是否允许对编译器进行一些自定义,已经进行了一些讨论,但我怀疑我们是否会看到这一点。
    【解决方案2】:

    命名空间约束没有任何价值。任何第三方都可以创建一个类并将该类放入同一个命名空间中。

    【讨论】:

      【解决方案3】:

      编译器不会为您执行此检查。不过,您可以在运行时验证此约束,也许在您的类型的静态构造函数中。

      【讨论】:

        【解决方案4】:

        最好的方法是创建一个接口并在你的类中使用这个接口,然后将此接口添加到你的约束中

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-27
          • 1970-01-01
          • 1970-01-01
          • 2015-11-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多