在String
课程中,有一种方法IsInterned()
。我从不使用这种方法。请帮助我理解这种方法的最佳用途。
答案 0 :(得分:9)
考虑实习是一种优化;它会降低一些理想的品质,以增加其他品质。特别是实习具有以下优点:
它具有以下不良品质:
作为一种优化,我们使用它,要么好的品质超重,要么质量不好(如果我们知道字符串将在应用程序的整个生命周期中使用) ,或者知道它将被多次使用,然后坏部分不会持有)。
出于同样的原因,我们不会使用它,因为糟糕的品质会超过好处。 (大部分时间)。
IsInterned()
可用于查找分数点。
考虑我有一个字符串属性Name
:
public string Name { get; set; }
让我们说我知道查找具有给定Name
的对象或尝试查找具有相同Name
的对象或以其他方式做很多事情很常见平等比较。或者说我知道会有很多其他具有相同Name
的对象。或两者。
在这些情况下,我可能会考虑实习:
private string _name;
public string Name
{
get { return _name; }
set { _name = string.Intern(value); }
}
当然,这是否是一个好主意取决于上面提到的实习的好坏。
中间使用和不使用是可能的:
private string _name;
public string Name
{
get { return _name; }
set { _name = string.IsInterned(value) ?? value; }
}
如果字符串value
已经被实习,那么我们实习的下方已经在工作,我们不再受苦,所以我们利用它。但如果value
尚未被实习,那么我们只是按原样使用它。
这也是一种优化,可以针对不同的情况进行优化。只有当看到的合理数量的值可能被某些其他代码(或者因为它们与程序集中的文字匹配)有效时,它才会受益,否则它只会浪费时间进行查找。它可能不如Intern()
有用,而kern.ipc.maxsockbuf=4194304 # (default 2097152)
net.inet.tcp.sendbuf_max=4194304 # (default 2097152)
net.inet.tcp.recvbuf_max=4194304 # (default 2097152)
net.inet.tcp.cc.algorithm=htcp # (default newreno)
net.inet.tcp.cc.htcp.adaptive_backoff=1 # (default 0 ; disabled)
net.inet.tcp.cc.htcp.rtt_scaling=1 # (default 0 ; disabled)
net.inet.ip.forwarding=1 # (default 0)
net.inet.ip.fastforwarding=1 # (default 0)
kern.ipc.soacceptqueue=1024 # (default 128 ; same as kern.ipc.somaxconn)
net.inet.tcp.mssdflt=1460 # (default 536)
net.inet.tcp.minmss=1300 # (default 216)
net.inet.tcp.rfc1323=1 # (default 1)
net.inet.tcp.rfc3390=1 # (default 1)
net.inet.tcp.sack.enable=1 # (default 1)
net.inet.tcp.tso=0 # (default 1)
net.inet.tcp.nolocaltimewait=1 # (default 0)
net.inet.tcp.experimental.initcwnd10=1 # (default 1 for FreeBSD 10.1)
net.inet.tcp.syncache.rexmtlimit=0 # (default 3)
net.inet.ip.rtexpire=2 # (default 3600)
net.inet.ip.rtminexpire=2 # (default 10 )
net.inet.tcp.syncookies=0 # (default 1)
net.inet.ip.check_interface=1 # verify packet arrives on correct interface (default 0)
net.inet.ip.process_options=0 # ignore IP options in the incoming packets (default 1)
net.inet.ip.redirect=0 # do not send IP redirects (default 1)
net.inet.ip.stealth=1 # do not reduce the TTL by one(1) when a packets goes through the firewall (default 0)
net.inet.icmp.drop_redirect=1 # no redirected ICMP packets (default 0)
net.inet.tcp.drop_synfin=1 # SYN/FIN packets get dropped on initial connection (default 0)
net.inet.tcp.fast_finwait2_recycle=1 # recycle FIN/WAIT states quickly (helps against DoS, but may cause false RST) (default 0)
net.inet.tcp.icmp_may_rst=0 # icmp may not send RST to avoid spoofed icmp/udp floods (default 1)
net.inet.tcp.msl=5000 # 5s maximum segment life waiting for an ACK in reply to a SYN-ACK or FIN-ACK (default 30000)
net.inet.tcp.path_mtu_discovery=0 # disable MTU discovery since most ICMP type 3 packets are dropped by others (default 1)
net.inet.udp.blackhole=1 # drop udp packets destined for closed sockets (default 0)
net.inet.tcp.blackhole=2 # drop tcp packets destined for closed ports (default 0)
security.bsd.see_other_uids=0 # users only see their own processes. root can see all (default 1)
反过来不仅仅是使用字符串而忽略实习,但确实显示了它可能有用的时间。
答案 1 :(得分:3)
如果你想锁定字符串值,可能会有一种用途。
以下内容:
string s = //get it from somewhere, e.g. a web request
lock (s){
//do something
}
存在问题,因为对同一字符串可能有两个不同的请求,但它们都输入受保护的代码。这是因为可能有两个不同的字符串对象具有相同的值。
然而,有一个叫做intern pool的东西,它是一个包含一些字符串实例的表(例如,所有文字都在那里)。
您可以使用它来锁定工作:
string s = //get it from somewhere, e.g. a web request
lock (string.Intern(s)){
//do something
}
此函数将返回对实习池中字符串的引用,该字符串与s具有相同的值,因此可以安全地锁定。
IsIntern
函数只是检查您持有的引用是否是对实习池中字符串的引用。
答案 2 :(得分:2)
请参阅Eric的帖子,我认为这是实习生解释的最佳位置
答案 3 :(得分:1)
C#中的字符串文字是实习的(也就是说,它们存储在实习池中) 对于文字的每次出现,只有一个实例。如果你自己做 语言(例如某些脚本系统),您可以使用IsInterned和Intern来产生 同样的事情。
答案 4 :(得分:0)
看看this。实际上该线程中有一个用例。