Ben izin ikame değerler sınıf var:Çalışma zamanında Interpolated [Adlandırıldı] değerleriyle String.Format gibi davranışlar nasıl alınır?
class MaskDictionary
{
public int id { get; set; }
public string last { get; set; }
public string lastinitial { get; set; }
public string first { get; set; }
public string firstinitial { get; set; }
public string salutation { get; set; }
public DateTime today { get; set; }
}
ve ben gibi, kullanıcı girişi gibi bir biçimlendirme dizesi almak istiyorum:
string userFormat = "{last}, {first} {today}";
ve aralara değer oluşturmak.
string.Format("{last}, {first} {today}", MaskDictionary);
ancak girdi dizesi dinamik hale başarısız ve: Kavramsal olarak benzer
çalışma zamanı biçimlendirme sağlamak için basit, temiz yolu nedirstring.Format(userFormat, MaskDictionary);
?
string userFormat = "{last}, {first} {today}";
PropertyInfo[] properties = typeof(MaskDictionary).GetProperties();
foreach (PropertyInfo property in properties)
{
userFormat = string.Replace(property.name, property.GetValue(mask));
}
gibi yansıma ve özyinelemeli yerine geçer kullanan bazı aksak seçenekleri vardır ama daha iyi bir yolu olmalı. answers--
karşılaştırılması
--update ben performansı için cevaplar iki çözüm önerilerini test edilmiş ve oldukça şaşırtıcı sonuçlar aldık.
static class Format2
{
static public string Format(string format, MaskDictionary md)
{
string val = format;
foreach (PropertyInfo property in typeof(MaskDictionary).GetProperties())
{
val = val.Replace("{" + property.Name + "}", property.GetValue(md).ToString());
}
return val;
}
}
static class Format1
{
public static string FormatWith(this string format, IFormatProvider provider, object source)
{
if (format == null)
throw new ArgumentNullException("format");
Regex r = new Regex(@"(?<start>\{)+(?<property>[\w\.\[\]]+)(?<format>:[^}]+)?(?<end>\})+",
RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
List<object> values = new List<object>();
string rewrittenFormat = r.Replace(format, delegate (Match m)
{
Group startGroup = m.Groups["start"];
Group propertyGroup = m.Groups["property"];
Group formatGroup = m.Groups["format"];
Group endGroup = m.Groups["end"];
values.Add((propertyGroup.Value == "0")
? source
: DataBinder.Eval(source, propertyGroup.Value));
return new string('{', startGroup.Captures.Count) + (values.Count - 1) + formatGroup.Value
+ new string('}', endGroup.Captures.Count);
});
return string.Format(provider, rewrittenFormat, values.ToArray());
}
}
Regex çözümü daha yavaş, çok daha yavaştır. 5 özellikli bir sözlük nesnesi ve bir 105 özellik sözlüğü nesnesine sahip bir kısa biçim dizesinin (20 karakter, 3 yer değiştirme) 1000 yineleme ve uzun biçim dizgisi (2000 karakter, 3 yer değiştirme) ve uzun bir sözlük nesnesi kullanıyorum. sonuçlar:
kısa biçim, küçük sözlüğü
Regex - 2150 msn
değiştirin - 3 ms
kısa biçim, büyük sözlüğü
Regex - 2160 msn
değiştirin - 30 ms
Uzun biçim, kısa Sözlük
Regex - 2170 ms
değiştirin - 26 ms
Uzun biçim, büyük sözlüğü
Regex - 2250 msn
değiştirin - 330 ms
büyük sözlükle de ölçek değildir değiştirin ama çok daha hızlı o aldığını başlar Büyük bir sözlük artı çok uzun bir biçim dizesi daha yavaş olacak. 105 özellik sözlüğü ile, işlemek için aynı miktarda almak için yaklaşık 16.000 karakter dizisi dizesi, ~ 2500ms aldı. 5 özellik küçük sözlük ile, regex asla hızlı değildi. 600K karakter formatlı bir dize regex için 14000 ms ve yerine geçmek için 7000 ms aldı ve 1.7M karakter formatı dizisi 38000 ms'ye karşılık 21000 ms aldı. Sözlük nesnesi makul boyutta ve biçim dizgesi 80 sayfadan kısa olduğu sürece kazanımları değiştirin.
Bunun gibi zarif bir şey yok ... –