.net 字符串-为什么';它不能实现无参数构造函数吗?

.net 字符串-为什么';它不能实现无参数构造函数吗?,.net,string,constraints,.net,String,Constraints,我想问System.String不包含无参数构造函数这一事实背后的想法是什么 因此,当存在new()约束时,不能使用此类型 更新 为什么您认为new string()是无用的,例如new int()不是无用的。我真的看不出有什么区别。我真的希望能够对string使用一个新的()约束,因为我期望的是string.Empty 更新2 我知道int是一种值类型,所有值类型都有默认的无参数构造函数。 我指的是@John Saunders answer(以及类似的答案),它指出说new String()基

我想问System.String不包含无参数构造函数这一事实背后的想法是什么

因此,当存在new()约束时,不能使用此类型

更新

为什么您认为new string()是无用的,例如new int()不是无用的。我真的看不出有什么区别。我真的希望能够对string使用一个新的()约束,因为我期望的是string.Empty

更新2

我知道int是一种值类型,所有值类型都有默认的无参数构造函数。 我指的是@John Saunders answer(以及类似的答案),它指出说new String()基本上没有任何用处。所以,如果new String()并不意味着任何有用的东西,那么new int()有什么用处呢?我还理解,值类型具有默认的无参数构造函数是很重要的。更重要的是,我认为字符串有一个默认的无参数构造函数会非常好。缺少无参数构造函数对我来说意味着一个对象如果没有初始化它的参数就无法存在。在我看来,字符串不需要任何参数,因为它可以是空的。我问这个问题是因为我想知道字符串没有无参数构造函数是否有一些重要原因,或者它只是设计或其他原因

更新3

我想这将是最后一次更新,因为它看起来更像一篇博客文章,而不是一个问题。在java中,字符串也是不可变的,new String()是完全合法的。但是,无参数构造函数的文档说明:

初始化新创建的字符串 对象,使其表示空 字符序列。注意,使用 此构造函数是不必要的,因为 字符串是不可变的

更新4

好的,上次更新;)我必须同意约翰·桑德斯的观点。我使用的代码具有new()约束,并且对于自定义类非常有效。然后,我的同事需要更改ints的代码,这样就可以了。然后将其更改为字符串,我们遇到了一个问题。当我现在思考这个问题时,我想我们正在使用的代码需要修改,以反映我们需要的是标量类型,而不是具有无参数构造函数的类。尽管如此,我仍然认为您可以编写新的int()而无法编写新的string()(是的,我知道int是一种值类型;),这有点不合理。谢谢你的回答

提前感谢您的帮助。

如果您可以使用

string s = new string();
你会用它做什么?字符串是不可变的


一些读者认为我说的是无参数字符串构造函数是无用的。我不是这个意思。我的意思是,从这样一个构造函数创建的空字符串在代码的其余部分将是无用的

记住OP说他想做的事:

public void SomeMethod<T>() where T : new()
{
    var t = new T();
    // Do _what_ now?
}

// Call:
SomeMethod<string>();
public void SomeMethod(),其中T:new()
{
var t=新的t();
//现在做什么?
}
//电话:
somethod();
我看不出在构建之后,你能用
t
做什么。

你会怎么做

String s = new String();
给你

String s = String.Empty;


没有实际字符串的字符串是什么

您可以这样做:

  String s = "hello world";
一旦你有了这个字符串,你就不能改变这个特定的字符串(strimgs是不可变的)。如果要声明空字符串,请执行以下操作:

string s = string.empty

字符串
对象称为不可变(只读),因为它的值 一旦创建,就无法修改。出现的方法 要修改
字符串
对象,实际上会返回一个新的
字符串
对象 包含修改的。如果有必要修改 类字符串对象的实际内容,请使用
System.Text.StringBuilder
班级


因此,无参数构造函数没有意义。

所有空字符串都是相同的。为什么要创建一个?您可以使用String.Empty或干脆使用“.”

我猜您希望能够定义一个如下所示的类:

public class SpecializedCollection<T> where T : new() {
    private List<T> _startingItems;

    public SpecializedCollection(int startingSize) {
        _startingItems = new List<T>(startingSize);
        for (int i = 0; i < startingSize; ++i)
            _startingItems.Add(new T());
    }

    // ... lots more code
}

当然,上述方法不适用于
string
,但适用于任何具有无参数构造函数的类(即,任何可以使用旧的
where t:new()
约束的类)。

这是泛型代码中的常见问题。C++用模板特化解决了它,但是C不支持。 但是,在C语言中,这并不能一目了然——最好的办法是使用
约束,然后使用基于反射的hack来默认构造
t
或使用
String.Empty
如果
t
System.String
。但是,如果使用其他不可默认构造的类,则会丢失编译器检查

还有一个选择:

class MyClass<T> where T : class
{
    public MyClass(T default)
    private T m_default;      
};

MyClass<object> instance = new MyClass<object>(new object());
MyClass<string> instance = new MyClass<string>(String.Empty);
class MyClass,其中T:class
{
公共MyClass(默认设置)
私人债务违约;
};
MyClass实例=新的MyClass(新对象());
MyClass实例=新的MyClass(String.Empty);
还有一个:

class MyClass<T> where T : class
{
    static SetDefault(T def)
    { 
       s_default = def;
    }
    static T s_default;      
};

MyClass<object> instance = new MyClass<object>(new object());
MyClass<string> instance = new MyClass<string>(String.Empty);
class MyClass,其中T:class
{
静态设置默认值(T def)
{ 
s_default=def;
}
静态T s_默认值;
};
MyClass实例=新的MyClass(新对象());
MyClass实例=新的MyClass(String.Empty);
“[为什么]System.String…不包含[a]无参数构造函数?”

因为它就是这样设计的。从这里的各种答案和观点中可以看出,对于无参数构造函数的需要或实现,甚至没有达成明确的共识。显然,从技术上讲,有一个默认构造函数可以初始化为
String.Empty
——因此BCL团队没有想到(不太可能),或者认为这是一个不值得的场景(可能)。FWIW,我同意-我不认为
string
上的默认ctor很重要

“你为什么认为新字符串()是我们的
var strings = new SpecializedCollection<string>(10, () => string.Empty);
public SpecializedCollection(int startingSize)
    : this(startingSize, Activator.CreateInstance<T>()) { }
class MyClass<T> where T : class
{
    public MyClass(T default)
    private T m_default;      
};

MyClass<object> instance = new MyClass<object>(new object());
MyClass<string> instance = new MyClass<string>(String.Empty);
class MyClass<T> where T : class
{
    static SetDefault(T def)
    { 
       s_default = def;
    }
    static T s_default;      
};

MyClass<object> instance = new MyClass<object>(new object());
MyClass<string> instance = new MyClass<string>(String.Empty);
private readonly Func<T> _defaultValueFactory = (Func<T>)DefaultT;
private Func<T> DefaultValueFactory
{
    get
    {
        return _defaultValueFactory;
    }
}

private static T DefaultT()
{
    return default(T);
}
public void DoSomething<T>() where T : new() { ... }
public void DoSomething<T>() where T : new() { DoSomething(() => new T()); }

public void DoSomething<T>(Func<T> constructor) { }
public void DoSomething<T>(T obj) { ... }
public T ShowForm<T>(Func<T> constructor) where T : Form
{
    T res = default(T);
    foreach(Form f in Application.OpenForms)
    {
        if (f is T)
        {
            res = (T)f;
            break;
        }
    }

    if (res == null)
        res = constructor();

    res.Focus();
    return res;
}