我们都知道StringJava 中是不可变的,但请检查以下代码:
String s1 = "Hello World";
String s2 = "Hello World";
String s3 = s1.substring(6);
System.out.println(s1); // Hello World
System.out.println(s2); // Hello World
System.out.println(s3); // World
Field field = String.class.getDeclaredField("value");
field.setAccessible(true);
char[] value = (char[])field.get(s1);
value[6] = 'J';
value[7] = 'a';
value[8] = 'v';
value[9] = 'a';
value[10] = '!';
System.out.println(s1); // Hello Java!
System.out.println(s2); // Hello Java!
System.out.println(s3); // World
Run Code Online (Sandbox Code Playgroud)
为什么这个程序运行这样?为什么价值s1和s2变化,但不是s3?
C#:你可以这样做,以便方法参数通过引用传递一个对象但是只读吗?
例如:
void MyMethod(int x, int y, read-only MyObject obj)
Run Code Online (Sandbox Code Playgroud)
where obj是对象引用,但在方法期间无法修改此对象.
这可以用C#实现吗?
我知道我不应该暴露一个List<T>属性,但我想知道这样做的正确方法是什么?例如,这样做:
public static class Class1
{
private readonly static List<string> _list;
public static IEnumerable<string> List
{
get
{
return _list;
//return _list.AsEnumerable<string>(); behaves the same
}
}
static Class1()
{
_list = new List<string>();
_list.Add("One");
_list.Add("Two");
_list.Add("Three");
}
}
Run Code Online (Sandbox Code Playgroud)
允许我的来电者简单地回到List<T>:
private void button1_Click(object sender, EventArgs e)
{
var test = Class1.List as List<string>;
test.Add("Four"); // This really modifies Class1._list, which is bad™
}
Run Code Online (Sandbox Code Playgroud)
所以,如果我想要一个真正不可变的List<T>,我总是要创建一个新的列表?例如,这似乎有效(测试在转换后为null):
public static IEnumerable<string> List
{
get
{
return new ReadOnlyCollection<string>(_list); …Run Code Online (Sandbox Code Playgroud) 使用这种方法来保持字符串的只读列表是好的,例如,ADO.NET中的字段列表.
var list = new System.Collections.ObjectModel.ReadOnlyCollection<string>(
new List<string>(4) { "type", "currency", "date", "amount" });
Run Code Online (Sandbox Code Playgroud)
或者这是一个多余的解决方案?
我想知道哪一个被认为是最干净或最好用的,为什么.
其中一个公开了一个乘客列表,让用户添加和删除等.另一个隐藏列表,只让用户枚举它们并使用特殊方法添加.
例1
class Bus
{
public IEnumerable<Person> Passengers { get { return passengers; } }
private List<Passengers> passengers;
public Bus()
{
passengers = new List<Passenger>();
}
public void AddPassenger(Passenger passenger)
{
passengers.Add(passenger);
}
}
var bus = new Bus1();
bus.AddPassenger(new Passenger());
foreach(var passenger in bus.Passengers)
Console.WriteLine(passenger);
Run Code Online (Sandbox Code Playgroud)
例2
class Bus
{
public List<Person> Passengers { get; private set; }
public Bus()
{
Passengers = new List<Passenger>();
}
}
var bus = new Bus();
bus.Passengers.Add(new Passenger());
foreach(var passenger in bus.Passengers)
Console.WriteLine(passenger); …Run Code Online (Sandbox Code Playgroud) 我想要一个带有(例如)SortedList集合"SrtdLst"属性的类"A",并且在这个类"A"中允许添加或减去"SrtdLst"项.但是在类"A"的实例中,只允许获取或设置项目的内容,而不是添加新项目或减去现有项目.在代码中:
class A
{
public SortedList<string, string> SrtdLst = new SortedList<string, string>();
public A()
{
// This must work:
SrtdLst.Add("KeyA", "ValueA");
// This too:
SrtdLst["KeyA"] = "ValueAAA";
}
}
class B
{
public A a = new A();
public B()
{
// I want the following code to fail:
a.SrtdLst.Add("KeyB", "ValueB");
// But this must work:
a.SrtdLst["KeyA"] = "ValueBBB";
}
}
Run Code Online (Sandbox Code Playgroud)
更新:我想创建一个类System.Data.SqlClient.SqlCommand.对于存储过程,您可以使用填充"参数"集合的成员"DeriveParameters",因此只能修改每个项目的值.
如何才能做到这一点?
c# ×5
.net ×2
collections ×2
readonly ×2
class ×1
getter ×1
immutability ×1
java ×1
list ×1
reflection ×1
setter ×1
string ×1