Я помещаю превосходный ответ JLBorges на аналогичный вопрос дословно из cplusplus.com, так как это наиболее краткое объяснение, которое я прочитал по этому вопросу.
] В шаблоне, который мы пишем, есть два типа имен, которые можно использовать - зависимые имена и не зависимые имена. Зависимое имя - это имя, которое зависит от параметра шаблона; неизменяемое имя имеет то же значение, независимо от параметров шаблона.
Например:
template< typename T > void foo( T& x, std::string str, int count ) { // these names are looked up during the second phase // when foo is instantiated and the type T is known x.size(); // dependant name (non-type) T::instance_count ; // dependant name (non-type) typename T::iterator i ; // dependant name (type) // during the first phase, // T::instance_count is treated as a non-type (this is the default) // the typename keyword specifies that T::iterator is to be treated as a type. // these names are looked up during the first phase std::string::size_type s ; // non-dependant name (type) std::string::npos ; // non-dependant name (non-type) str.empty() ; // non-dependant name (non-type) count ; // non-dependant name (non-type) }
То, что зависит от зависимого имени, может быть чем-то другим для каждого конкретного экземпляра шаблона. Как следствие, шаблоны C ++ подвержены «двухфазному поиску имен». Когда шаблон сначала анализируется (до того, как выполняется какое-либо создание), компилятор просматривает не зависящие имена. Когда происходит конкретное создание шаблона, параметры шаблона известны к тому времени, и компилятор ищет зависимые имена.
На первом этапе анализатор должен знать, является ли зависимое имя именем типа или имени не-типа. По умолчанию зависимым именем считается имя не-типа.
Использовать ключевое слово typename только в объявлениях шаблонов и определениях, приведенных ниже.
blockquote>у вас есть квалифицированное имя, которое относится к типу и зависит от параметра шаблона.
Нет никакого встроенного метода для обработки этого.
string myString = "{foo} is {bar} and {yadi} is {yada}".Inject(o);
Status.Text = "{UserName} last logged in at {LastLoginDate}".FormatWith(user);
, треть А улучшила метод частично на основе двух выше от Phil Haack
string language = "Python";
int numquotes = 2;
string output = language + " has "+ numquotes + " language types.";
Редактирование: То, что я должен был сказать, было, "Нет, я не верю тому, что Вы хотите сделать, поддерживается C#. Это настолько близко, как Вы собираетесь добраться".
Я сомневаюсь, что это будет возможно. Первая вещь, которая приходит на ум, состоит в том, как Вы собираетесь получить доступ к именам локальной переменной?
мог бы быть некоторый умный способ использовать LINQ и Лямбда-выражения, чтобы сделать это как бы то ни было.
Я думаю самое близкое, которое Вы получите, индексируемый формат:
String.Format("{0} has {1} quote types.", "C#", "1");
существует также Строка. Замена (), если Вы готовы сделать это на нескольких шагах и взять его на вере, что Вы не найдете свои 'переменные' больше нигде в строке:
string MyString = "{language} has {n} quote types.";
MyString = MyString.Replace("{language}", "C#").Replace("{n}", "1");
Расширение этого для использования Списка:
List<KeyValuePair<string, string>> replacements = GetFormatDictionary();
foreach (KeyValuePair<string, string> item in replacements)
{
MyString = MyString.Replace(item.Key, item.Value);
}
Вы могли сделать это с Dictionary< строка, строка> также путем итерации это-.Keys наборы, но при помощи List< KeyValuePair< строка, строка>> мы можем использовать в своих интересах.ForEach Списка () метод и уплотнить его назад к остроте:
replacements.ForEach(delegate(KeyValuePair<string,string>) item) { MyString = MyString.Replace(item.Key, item.Value);});
лямбда А была бы еще более простой, но я нахожусь все еще на.Net 2.0. Также обратите внимание, что.Replace () производительность не является звездной, когда используется многократно, так как строки в.Net неизменны. Кроме того, это требует MyString
, переменная определяется таким способом, которым это доступно для делегата, таким образом, это еще не прекрасно.
См. https://stackoverflow.com/questions/271398? page=2#358259
Со связанным - к расширению можно записать это:
var str = "{foo} {bar} {baz}".Format(foo=>"foo", bar=>2, baz=>new object());
и Вы доберетесь "foo 2 System.Object
".
Сама платформа не позволяет делать это, но можно смотреть на это сообщение Scott Hanselman. Использование в качестве примера:
Person p = new Person();
string foo = p.ToString("{Money:C} {LastName}, {ScottName} {BirthDate}");
Assert.AreEqual("$3.43 Hanselman, {ScottName} 1/22/1974 12:00:00 AM", foo);
Этот код James Newton-King подобен и работает с подсвойствами и индексами,
string foo = "Top result for {Name} was {Results[0].Name}".FormatWith(student));
, код James полагается Система. Сеть. UI.DataBinder для парсинга строки и требует Системы ссылки. Сеть, которую некоторым людям не нравится делать в невеб-приложениях.
РЕДАКТИРОВАНИЕ: О, и они работают приятно с анонимными типами, если у Вас нет объекта со свойствами готовым к нему:
string name = ...;
DateTime date = ...;
string foo = "{Name} - {Birthday}".FormatWith(new { Name = name, Birthday = date });
Кажется, нет способа сделать это из поля. Хотя, выглядит выполнимым реализовать Ваше собственное IFormatProvider
, который связывается с IDictionary
для значений.
var Stuff = new Dictionary<string, object> {
{ "language", "Python" },
{ "#", 2 }
};
var Formatter = new DictionaryFormatProvider();
// Interpret {0:x} where {0}=IDictionary and "x" is hash key
Console.WriteLine string.Format(Formatter, "{0:language} has {0:#} quote types", Stuff);
Выводы:
Python has 2 quote types
протест состоит в том, что Вы не можете смешаться FormatProviders
, таким образом, необычное текстовое форматирование не может использоваться одновременно.
У меня есть реализация, которую я просто разместил в своем блоге здесь: http://haacked.com/archive/2009/01/04/fun-with-named-formats-string-parsing-and-edge-cases.aspx
Это решает некоторые проблемы, которые эти другие реализации имеют с выходом фигурной скобки. Сообщение имеет детали. Это делает DataBinder. Вещь оценки также, но все еще очень быстро.