Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 有没有一种方法可以指定where T:new()限制,但使用内部构造函数?_C#_.net_Generics_Restriction - Fatal编程技术网

C# 有没有一种方法可以指定where T:new()限制,但使用内部构造函数?

C# 有没有一种方法可以指定where T:new()限制,但使用内部构造函数?,c#,.net,generics,restriction,C#,.net,Generics,Restriction,我创建了一个需要实例化其实现类型的泛型类,因此实现类型必须有一个可访问的无参数构造函数。看起来new()限制可以完成这项工作,但是它强制实现类型在我有一个内部的公共构造函数时具有公共构造函数(但是可以访问,因为两者都在同一个程序集上) 是否有理由强迫它公开而不是“可访问” 有没有办法满足我的需要 提前谢谢 编辑:这样做的原因是我有一个必须通过单例使用的类X。Singleton类是一个泛型类,我希望将class X构造函数设置为内部,以避免外部用户以错误的方式访问对象(调用构造函数) 是否有理由强

我创建了一个需要实例化其实现类型的泛型类,因此实现类型必须有一个可访问的无参数构造函数。看起来new()限制可以完成这项工作,但是它强制实现类型在我有一个内部的公共构造函数时具有公共构造函数(但是可以访问,因为两者都在同一个程序集上)

  • 是否有理由强迫它公开而不是“可访问”
  • 有没有办法满足我的需要
  • 提前谢谢

    编辑:这样做的原因是我有一个必须通过单例使用的类X。Singleton类是一个泛型类,我希望将class X构造函数设置为内部,以避免外部用户以错误的方式访问对象(调用构造函数)

    是否有理由强迫它公开而不是“可访问”

    根据体系结构,术语“可访问”是非常上下文敏感的,而泛型则不是。 在您的特定情况下,
    internal
    可以访问,但泛型是为泛型解决方案而设计的

    有没有办法满足我的需要


    基于第一点,不,这是不可能的,我也不知道。

    泛型用于泛型解决方案,因此,如果使用“新”约束,您的解决方案必须与实现公共构造函数的每个类一起工作

    如果您想为特定类型的类实现一个通用解决方案,您可以定义一个抽象基类来实现这样的内部构造函数。实现此抽象基类的通用解决方案并使用

    * 其中T:MyBaseClassWithInternalCtor *


    作为约束。

    规范绑定和未绑定类型第4.4.3节中概述的C语言不允许这样做

    如果约束是构造函数约束
    new()
    ,则类型
    A
    不能是
    abstract
    ,并且必须具有公共无参数构造函数。如果满足以下条件之一,则满足此条件

    • A
      是一种值类型,因为所有值类型都有一个公共默认构造函数
    • A
      是具有协构造函数约束的类型参数
    • A
      是具有值类型约束的类型参数
    • A
      是一个非
      abstract
      的类,它包含一个显式声明的
      public
      构造函数,没有参数
    • A
      不是
      abstract
      ,具有默认构造函数
    如果不满足这些条件中的任何一个,则会出现编译器错误。如果您发现自己拥有的类型是公共的,但只具有内部构造函数,那么它们很可能实际上应该是具有公共构造函数的内部类型

    我建议将类型访问器更改为
    内部
    ,将其构造函数更改为
    公共
    ,并使其无参数。然后,您的
    public
    无参数构造函数可以通过调用非无参数
    private
    内部
    构造函数来执行任何额外的初始化工作

    internal class C<T> where : T new()
    {
        public C() : this(new T()) {
        }
    
        private C(T t) {
            // Do additional initialization
        }
    }
    
    根据您的更新,这里有一个公共单身模式的小例子

    public class Singleton<T> where T : new()
    {
        public static Singleton<T> Current {
            get;
            private set;
        }
    
        internal Singleton() : this(new T()) {
        }
    
        private Singleton(T t) {
            Current = this;
            // Do whatever you need to with T
        }        
    
        public String Name {
            get;
            set;
        }
    }
    
    公共类单例,其中T:new()
    {
    公共静态单态电流{
    得到;
    私人设置;
    }
    内部单例():此(新的T()){
    }
    私人单身人士(T){
    电流=这个;
    //用T做你想做的事
    }        
    公共字符串名{
    得到;
    设置
    }
    }
    
    用法

    //内部程序集中的某个地方
    Singleton Singleton=新Singleton();
    //在外部组件中
    Singleton.Current.Name=“SoMoS”;
    
    您甚至不需要以这种方式使用构造函数,您也可以轻松地做一些简单的事情

    public class Singleton<T> where T : new()
    {
        public static Singleton<T> Current {
            get;
            private set;
        }
    
        internal Singleton() {
            T t = new T();
            // Do stuff with T
        }
    
        public String Name {
            get;
            set;
        }
    }
    
    公共类单例,其中T:new()
    {
    公共静态单态电流{
    得到;
    私人设置;
    }
    内部单态(){
    T=新的T();
    //用T做东西
    }
    公共字符串名{
    得到;
    设置
    }
    }
    

    如果你不能设计出符合你需求的泛型,那么泛型可能不是你的选择。泛型只能做这么多,并不能解决所有问题。有工厂模式、注入等,将类内部化,并将构造函数公开。如果类必须是公共的,那么不可以。谢谢,请参阅我的编辑以了解内部构造函数更新我的答案的原因。您可能需要更仔细地考虑一下您的设计,因为泛型可能不是最合适的。在我看来,编译器可以在编译时检查构造函数是否可以访问,或者只有在不能从泛型类调用新构造函数时才会引发错误。无论如何,谢谢您的解释。@SoMoS:问题是,具有
    new()
    约束的类型
    T
    很可能会传递给不同程序集中的例程。虽然编译器在某些情况下可能会确定特定类型参数
    T
    永远无法传递到特定程序集之外,但在许多情况下,这种推断是不可能的。只有当编译器能够推断出它是安全的时,才允许具有
    内部
    无参数构造函数的类型满足
    新的()
    约束,这意味着在允许这种使用时有一些非常奇怪的规则。@SoMos:您要的是一些特殊的
    内部新的()
    定义,你可以用西班牙语来定义它。为什么现在不推断呢?我认为这是关于不同程序集之间的类型共享。如果我想使用某个运行时类型的泛型,而该泛型无法从“外部”访问…@Tigran:当然,当运行时出现问题时总是会发生什么,请引发异常。我真的不明白为什么这个约束在编译时强制执行,而不是在运行时执行。@SoMo
    // Somewhere in your internal assembly
    Singleton<String> singleton = new Singleton<String>();
    
    // In an external assembly
    Singleton.Current.Name = "SoMoS";
    
    public class Singleton<T> where T : new()
    {
        public static Singleton<T> Current {
            get;
            private set;
        }
    
        internal Singleton() {
            T t = new T();
            // Do stuff with T
        }
    
        public String Name {
            get;
            set;
        }
    }