[英]What is the purpose of String.IsInterned?
In the String
class there is a method IsInterned()
. 在String
类中有一个方法IsInterned()
。 I never use this method. 我从不使用这种方法。 Please help me to understand the best uses of this method. 请帮助我了解这种方法的最佳用途。
Consider that interning is an optimisation; 考虑到实习是一种优化; it trades a decrease in some desirable qualities for an increase in others. 它会降低一些理想的品质,以增加其他品质。 In particular interning has the following good qualities: 特别是实习具有以下优点:
It has the following bad qualities: 它具有以下不良品质:
As an optimisation, we use it where the either the good qualities out-weigh the bad or where the bad qualities don't hold (if we know the string is going to be around for the lifetime of the application anyway, or know it will be used many times, then the bad part doesn't hold). 作为一种优化,我们使用它来衡量好的品质或者质量不好的地方(如果我们知道字符串将会在应用程序的整个生命周期中出现,或者知道它会多次使用,然后坏部分不成立)。
And by the same token we don't use it where the bad qualities will out-weigh the good. 并且出于同样的原因,我们不会使用它,因为糟糕的品质会超过好处。 (Most of the time). (大多数时候)。
IsInterned()
can be used to find a part-way point. IsInterned()
可用于查找部分点。
Consider I have a string property Name
: 考虑我有一个字符串属性Name
:
public string Name { get; set; }
Let's say I know that it's common to look for objects with a given Name
, or to try to find objects with the same Name
or otherwise do a lot of equality comparisons on it. 假设我知道查找具有给定Name
对象是常见的,或者尝试查找具有相同Name
对象,或者对其进行大量的相等比较。 OR Let's say I know there will be a lot of other objects with the same Name
. 或者假设我知道会有很多其他具有相同Name
对象。 OR Both. 或两者。
In these cases I might consider interning: 在这些情况下,我可能会考虑实习:
private string _name;
public string Name
{
get { return _name; }
set { _name = string.Intern(value); }
}
Of course, whether this was a good idea or not depends on the good and bad qualities of interning mentioned above. 当然,这是否是一个好主意取决于上面提到的实习的好坏。
In-between using and not using is the possibility: 中间使用和不使用是可能的:
private string _name;
public string Name
{
get { return _name; }
set { _name = string.IsInterned(value) ?? value; }
}
Here if the string value
is already interned then we the down-sides of interning are already at work and we don't suffer any more, so we take advantage of it. 如果字符串value
已经被实习,那么我们实习的下方已经在工作,我们不再受苦,所以我们利用它。 But if value
is not already interned then we just use it as-is. 但如果value
尚未实现,那么我们只是按原样使用它。
This is also an optimisation, that optimises for a different case. 这也是一种优化,可以针对不同的情况进行优化。 It only benefits if a reasonable number of the values seen are likely to be interned by some other code (or because they match literals in the assembly), otherwise it just wastes time doing lookups. 只有当看到的合理数量的值可能被某些其他代码(或者因为它们与程序集中的文字匹配)有效时,它才会受益,否则它只会浪费时间进行查找。 It's probably less often useful than Intern()
which in turn is less often useful than just using the strings and ignoring interning, but that does show a time when it could be useful. 它可能不如Intern()
有用,后者反过来不仅仅是使用字符串而忽略实习,但确实显示了它可能有用的时间。
One possible use would be if you want to lock on the string value. 一种可能的用法是如果要锁定字符串值。
In the following: 在下面的:
string s = //get it from somewhere, e.g. a web request
lock (s){
//do something
}
there is a problem, because there might be two different requests for the same string, but they both enter the protected code. 有一个问题,因为对同一个字符串可能有两个不同的请求,但它们都输入受保护的代码。 This is because there might be two different string objects that has the same value. 这是因为可能存在两个具有相同值的不同字符串对象。
However there is something called intern pool, which is a table that contains a single instance of some strings (all the literals are there for example). 但是有一个叫做intern pool的东西,它是一个包含一些字符串实例的表(例如,所有的文字都在那里)。
You can use it to make the locking work: 您可以使用它来锁定工作:
string s = //get it from somewhere, e.g. a web request
lock (string.Intern(s)){
//do something
}
This function would return a reference to a string in the intern pool, which has the same value as s, so is safe for locking. 此函数将返回对实习池中字符串的引用,该字符串与s具有相同的值,因此可以安全地锁定。
The IsIntern
function simply checks whether the reference you are holding is a reference to a string on the intern pool. IsIntern
函数只检查您持有的引用是否是对实习池中字符串的引用。
请参阅Eric的帖子,我认为这是Intern的最佳解释
String literals in C# are interned (that is, they are stored into an intern pool) so that for each occurrence of the literal there is only one instance. C#中的字符串文字是固定的(也就是说,它们存储在实习池中),因此对于文字的每次出现,只有一个实例。 If you are making your own language (for example some script system), you can use IsInterned and Intern to yield the same thing. 如果您使用自己的语言(例如某些脚本系统),则可以使用IsInterned和Intern来生成相同的内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.