C# 当使用对象初始值设定项实例化对象时,如何向列表类型的属性添加项?
我希望C# 当使用对象初始值设定项实例化对象时,如何向列表类型的属性添加项?,c#,C#,我希望Books不为null,因此我将其设置为初始化的只读属性,如下所示 class Author { public int Id { get; set; } public string Name { get; set; } public List<string> Books { get; } = new List<string>(); } class Project { void Main() { Author
Books
不为null
,因此我将其设置为初始化的只读属性,如下所示
class Author
{
public int Id { get; set; }
public string Name { get; set; }
public List<string> Books { get; } = new List<string>();
}
class Project
{
void Main()
{
Author a = new Author
{
Id = 100,
Name = "Bill Gates"
};
a.Books.AddRange(new string[] { "Asp.net", "C++", "C#" });
}
}
问题:
使用对象初始值设定项可以简化a
的实例化(以及填充书籍
)吗?类作者
class Author
{
public int Id { get; set; }
public string Name { get; set; }
public List<string> Books { get; } = new List<string>();
public Author(params string[] books)
{
Books.AddRange(books);
}
}
class Project
{
void Main()
{
Author a = new Author("Asp.net", "C++", "C#")
{
Id = 100,
Name = "Bill Gates"
};
}
}
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共列表书籍{get;}=new List();
公共作者(参数字符串[]图书)
{
图书。添加范围(图书);
}
}
班级项目
{
void Main()
{
作者a=新作者(“Asp.net”、“C++”、“C#”)
{
Id=100,
Name=“比尔·盖茨”
};
}
}
类作者
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共列表书籍{get;}=new List();
公共作者(参数字符串[]图书)
{
图书。添加范围(图书);
}
}
班级项目
{
void Main()
{
作者a=新作者(“Asp.net”、“C++”、“C#”)
{
Id=100,
Name=“比尔·盖茨”
};
}
}
您可以使用专用设置
public class Author
{
public int Id { get; set; }
public string Name { get; set; }
public List<string> Books { get; private set; }
public Author(params string[] books)
{
Books = new List<string>(books);
}
}
公共类作者
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共列表图书{get;private set;}
公共作者(参数字符串[]图书)
{
图书=新列表(图书);
}
}
或者使用just get(只读选项)
公共类作者
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共列表图书{get;}
公共作者(参数字符串[]图书)
{
图书=新列表(图书);
}
}
private选项我可以在Author内部随时更改列表的实例,但是Author外部的任何其他类都可以读取它
只读选项我无法随时更改。我在构造函数中初始化它,之后它将永远不会更改
您还可以使用只读集合,初始化后任何主体都不会添加或删除书籍
public class Author
{
public int Id { get; set; }
public string Name { get; set; }
public ReadOnlyCollection<string> Books { get; }
public Author(params string[] books)
{
Books = new ReadOnlyCollection<string>(books);
}
}
公共类作者
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共只读收集书籍{get;}
公共作者(参数字符串[]图书)
{
图书=新的只读集合(图书);
}
}
您可以使用专用设置
public class Author
{
public int Id { get; set; }
public string Name { get; set; }
public List<string> Books { get; private set; }
public Author(params string[] books)
{
Books = new List<string>(books);
}
}
公共类作者
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共列表图书{get;private set;}
公共作者(参数字符串[]图书)
{
图书=新列表(图书);
}
}
或者使用just get(只读选项)
公共类作者
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共列表图书{get;}
公共作者(参数字符串[]图书)
{
图书=新列表(图书);
}
}
private选项我可以在Author内部随时更改列表的实例,但是Author外部的任何其他类都可以读取它
只读选项我无法随时更改。我在构造函数中初始化它,之后它将永远不会更改
您还可以使用只读集合,初始化后任何主体都不会添加或删除书籍
public class Author
{
public int Id { get; set; }
public string Name { get; set; }
public ReadOnlyCollection<string> Books { get; }
public Author(params string[] books)
{
Books = new ReadOnlyCollection<string>(books);
}
}
公共类作者
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共只读收集书籍{get;}
公共作者(参数字符串[]图书)
{
图书=新的只读集合(图书);
}
}
由于这个限制,我必须先用对象初始值设定项实例化对象a[emphasis mine],然后通过AddRange填充其Books属性
但是客户端可以将Books设置为null,这是我不想要的
这些警报都是通过使用构造函数来响应的。构造函数的目的是创建有效的对象。构造函数保证一个有效的对象,因为它强制用户提供所需的参数,然后应用其内部状态规则。没有构造函数,用户和每个用户都有责任强制执行该类的规则,并正确执行
读者会觉得,实例化一个对象是为了确保部分状态,然后允许外部代码随意地把它搞砸,这是讽刺和不协调的
编辑
回复:“我被迫”的评论
你只专注于解决一半的问题。例如,Name
为null或空字符串真的可以吗?没有名字的作者是什么?对空名称字符串调用方法会引发异常。要么在构造函数中处理它的所有内容,要么编写错误捕获程序,包括客户端代码。客户端代码不应修复作者的缺点
但是,如果你必须的话,你可以这样做。这种“延迟初始化”并不能消除对一个好的构造函数的需求
public List<string> Books {
get{ return value; }
set { if (Books == null) {
Books = new List<string>();
} else { Books = value; }
}
}
公共列表图书{
获取{返回值;}
设置{if(Books==null){
书籍=新列表();
}else{Books=value;}
}
}
但那是马车。可以删除现有列表
public Author (string name, List<string> books = null) {
if(String.isNullOrWhiteSpace(name))
throw new ArgumentException("name is missing");
// P.S. no public setter properties to undo construction
Name = name;
Books = books;
}
// suggestion: rewrite to use params keyword to add 1 - many at once
public void AddBook( title) {
if (String.isNullORWhitespace(title)) return;
Books.Add(title); // allows duplicates, fyi.
public Author(字符串名,列表簿=null){
if(String.isNullOrWhiteSpace(name))
抛出新ArgumentException(“缺少名称”);
//P.S.无可撤消构造的公共setter属性
名称=名称;
书=书;
}
//建议:重写以使用params关键字一次添加1-多个
公共无效地址簿(标题){
if(String.isNullORWhitespace(title))返回;
Books.Add(title);//允许复制,仅供参考。
如果有人想投票,那就投票吧。他在前面有效地说明了这一点。我只是想解释健壮构造函数的优点
public List<string> Books {
get{ return value; }
set { if (Books == null) {
Books = new List<string>();
} else { Books = value; }
}
}
结束编辑
由于这个限制,我必须先用对象初始值设定项实例化对象a[emphasis mine],然后通过AddRange填充其Books属性
但是客户可以设置帐簿