|
|
Comments and Discussions
|
|
 |

|
I have submitted an article with code that performs similar functionality to yours. Custom Formatting in .NET - Enhancing String.Format to all new levels![^]
It has a plugin system that allows custom formatting like yours, it has Conditional Formatting, and it allows syntax such as:
result = CustomFormat("{Name} is {Age} years old", person)
Take a look if you are interested, and let me know if there are areas for improvement!
|
|
|
|

|
Copy & Paste from MSDN. Article has no value.
|
|
|
|

|
i have a column which have value as string such as 06563010212138000129.
when i try to display to a datagrid it become : 6,563010212138E+18
i want to display it with its original value...
how to do it ??
note, this record from a csv file....
please help me...
|
|
|
|

|
Hi
I want to write some data on file like given below
sw.WriteLine("{0,15}{1,15}",BlockName, ApplicantName);
If BlockName exceed 15 characters it will write complete BlockName and the ApplicantName. How I can force my formatting so that maximum 15 characters of BlockName written on file.
Sheraz
|
|
|
|

|
Thanks for the article. I see this snippet of code:
StringFormatInfo fmtinfo = new StringFormatInfo();
string.Format(fmtinfo, @"The morse code for ""{0}"":\n{0:m}", "Hello, world");
I'm wondering if there is a way (in .NET 2.0) to get the StringFormatInfo() instance to somehow be "registered" with the runtime such that the "m" code can be used in any formatting string without requiring an additional argument.
For example, .NET already supports "n", "d", "g" and others without having to pass in a format info instance everywhere.
Is there a call, or set of calls, that would add "m" to that list so one could simply write:
string.Format("The code is: {0:m}", "Hello");
?
|
|
|
|

|
Not that I know of. You could create a container, which would contain the string. Implement IFormattable on your container type. You could even implement an implicit cast operator to/from string to make it easier to use.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Customer Product-lifecycle Experience
Microsoft
[My Articles] [My Blog]
|
|
|
|

|
This article was great, and I got things to work just fine. However, I'd really like to use my new format provider in the DataFormatString expression on the GridView of ASP.NET 2.0. How can I make this available to the GridView? I could use template columns and programatically use my format, but I'd like to call it directly within a BoundField column in the GridView.
Possible? Any help left on this article?
|
|
|
|

|
In your template just set the DataFormatString. The documentation for the BoundField.DataFormatString property even has an example. I'm not sure what you mean by "but I'd like to call it directly...".
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Customer Product-lifecycle Experience
Microsoft
[My Articles] [My Blog]
|
|
|
|

|
Thanks for responding so quickly, Heath. What I mean by "calling it directly" was that just that I want to be able to use the DataFormatString="" attribute on the BoundField for my GridView. I've implemented my IFormatProvider class and I get the correct results when using it through the code like so:
ret = String.Format(new PropperString(), "{0:PS}", DataBinder.Eval(objRow, "BandName").ToString());
But when I try to use my new PropperString ("PS") format in the GridView DataFormatString attribute, it doesn't work.
DataFormatString="{0:PS}"
Also, I have this class in a separate project than the ASP.NET web app I'm calling it from. I do have a reference in my project, will that make a difference in attempting the DataFormatString attribute usage?
Mason
|
|
|
|

|
The article here isn't applicable. The inner workings of the DataBoundControl and its child classes is different than what is described here. If you want to format an object completely different, derive a new class from BoundField and override FormatDataValue. This method is actually defined in the base class DataControlField, so you can derive your class from that as well but you should find a class that functions as closely as you want to avoid having to override and provide more functionality on your own.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Customer Product-lifecycle Experience
Microsoft
[My Articles] [My Blog]
|
|
|
|

|
I am having a great deal of difficulty in using the ICustomFormatter / IFormatProvider pattern when formatting a long using the Long.ToString() method.
Can Heath or anyone explain how to use a custom formatter in this scenario?
When I execute the code below using Heath's Samples.NumberFormatInfo class, I cannot get roman numeral formatting when I call the overloaded Long.ToString() methods passing the custom formatter.
Samples.NumberFormatInfo info = new Samples.NumberFormatInfo();
long someLong = 25;
// behaves as expected as per the article
String test1 = string.Format( info, "{0}: {0:rn}", someLong);
Console.WriteLine(test1);
// doesn't invoke the Samples.NumberFormatInfo Format method
String test2 = someLong.ToString("0:rn", info);
Console.WriteLine(test2);
// doesn't invoke the Samples.NumberFormatInfo Format method
String test3 = someLong.ToString(info);
Console.WriteLine(test3);
Normally I would be able to work around this by just calling String.Format, butI am trying to register my own custom IFormatProvider to a Windows Forms DataGridViewCellStyle object, which I believe ends up calling .ToString(string,IFormatProvider) internally when formatting data.
Is this a known bug or am I missing something?
|
|
|
|

|
I recommend for the sake of learning to use either ildasm.exe from the .NET Framework SDK or search for ".NET Reflector" (or another decompiler) and look at the implementation for Int64.ToString(). It might not call into IFormatProvider implementations.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Customer Product-lifecycle Experience
Microsoft
[My Articles] [My Blog]
|
|
|
|

|
Hi Heath -
The documentation for ICustomFormatter reads:
"For example, use this interface to provide custom formatting of the value of an object by the String.Format or Int32.ToString methods."
It's pretty clear there is a bug in the System.Int32, System.Int64, and System.Double implementations of IFormattable.ToString(string format, IFormatProvider formatProvider), which will *not* use a custom IFormatProvider implementing ICustomFormatter if provided.
I've looked at the types in question in Lutz Roeder's .NET Reflector.
Looking at the implementation in .NET Framework 2.0, I see:
System.String.Format(IFormatProvider provider, string format, params object[] args)
- does some error checking and creates a StringBuilder and calls StringBuilder.AppendFormat, which when decompiled shows:
System.Text.StringBuilder.AppendFormat(IFormatProvider provider, string format, params object[] args)
{
.....
if (provider != null)
{
formatter1 = (ICustomFormatter) provider.GetFormat(typeof(ICustomFormatter));
}
....
if (formatter1 != null)
{
// Great, calls the supplied ICustomFormatter.Format method
text2 = formatter1.Format(text1, obj1, provider);
}
... otherwise cast obj1 to IFormattable and call IFormattable.ToString
}
So that looks good which is why String.Format works.
However, looking at System.Int64.ToString(string format, IFormatProvider provider) reveals it never tries to get an ICustomFormatter, no matter what format provider is passed in or what the format string is.
public string ToString(string format, IFormatProvider provider)
{
return Number.FormatInt64(this, format, NumberFormatInfo.GetInstance(provider));
}
Unfortunately, Number.FormatInt64 takes a (sealed) NumberFormatInfo and not an IFormatProvider, and NumberFormatInfo.GetInstance(IFormatProvider formatProvider) always returns a NumberFormatInfo and not an IFormatProvider.
NumberFormatInfo.GetInstance does call into the supplied formatProvider's GetFormatmethod, but passes in typeof(NumberFormatInfo) never typeof(ICustomFormatter).
I believe that the Int64.ToString(string format, IFormatProvider formatProvider) call sequence needs to at some point call and test the results of formatProvider.GetFormat(typeof(ICustomFormatter)) to allow custom formatting as per the documentation of System.IFormatProvider.GetFormat in the .NET Framework SDK Class Library Reference.
I believe this is a bug in Int64.ToString(string format, IFormatProvider formatProvider) and similarly in Double.ToString(string format, IFormatProvider formatProvider) in their implementations of IFormattable.ToString(string format, IFormatProvider formatProvider) .
There doesn't appear to be a workaround for this bug when trying to provide a custom IFormatProvider in a System.Windows.Forms.DataGridView.DataGridViewCellStyles.
When looking at the decompiled System.Windows.Forms.DataGridViewCell class, this uses an internal implementation class called System.Windows.Forms.Formatter, this class has a FormatObjectInternal method defined as:
private static object FormatObjectInternal(object value, Type targetType, TypeConverter sourceConverter, TypeConverter targetConverter, string formatString, IFormatProvider formatInfo, object formattedNullValue)
{
...
if (((targetType == Formatter.stringType) && (value is IFormattable)) && !string.IsNullOrEmpty(formatString))
{
// This calls the broken Int64.ToString method
return (value as IFormattable).ToString(formatString, formatInfo);
}
... then check if there's a TypeConverter, etc. etc
}
It appears that there is no way to use a custom IFormatProvider/ICustomFormatter implementation to do custom formatting in a DataGridView, by setting the DataGridViewCellStyles.Format and FormatProvider properties.
Update: There is a workaround for using this in the DataGridView, by implementing the DataGridView.CellFormatting event.
void mGrid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
DataGridViewColumn col = mGrid.Columns[e.ColumnIndex];
if (col.DefaultCellStyle.FormatProvider is ICustomFormatter)
{
Object originalData = e.Value;
e.Value = String.Format(col.DefaultCellStyle.FormatProvider, col.DefaultCellStyle.Format, originalData);
}
}
This works by calling String.Format rather than letting the Windows Forms formatting infrastructure call the broken IFormattable.ToString method for the native numeric types.
- Gabriel
-- modified at 17:39 Monday 11th September, 2006
|
|
|
|

|
Excellent analysis! It appears to be a bug, yes. I recommend going to Windows Connect[^] and filing a bug against the runtime. They may have a specific reason for it, too.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Customer Product-lifecycle Experience
Microsoft
[My Articles] [My Blog]
|
|
|
|

|
Thanks Heath for pointing me to Windows Connect.
I raised bug 201155, we'll see what they say.
- g
|
|
|
|

|
I have read the FAQs and your suggession. But, I did not get it properly
Maybe I haven't capablity to read it OR
You have not presented it Deeply.
Whatever pl. make it easy to understand and with more examples.
MKBELIM
|
|
|
|

|
Dim myName As String = "ALEX"
Dim myFinalText As String
myFinalText = String.Format("My name is : {0}", myName)
myFinalText = "My name is : " + myName
in your article you mention about "I'm sure you'll agree that the string format expression is much easier to read and change at runtime."
So i would like to know is there other benefit using the string format like the performance issue, is that any different?
Thank you
|
|
|
|

|
For something like that I wouldn't recommend string formatting in every case. If you were going to localize your application, however, string formatting lets you keep the same parameter list but localize and store the format. My article discusses this as a main point, comparing it with what developers have to do in C/C++ and Perl.
Words don't always go in the same order in different languages and simple string concatenation will make localizing your application very difficult.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Customer Product-lifecycle Experience
Microsoft
[My Articles] [My Blog]
|
|
|
|

|
thank you alot for you advise
|
|
|
|

|
String concatenation causes various performance issues as new immutable strings are created every time concatenation is done. Are these issues mitigated when String.Format is used?
i.e. does doing string.Format("My name is: {0} {1}", FirstName, LastName) create three strings and concatenate the variables to the original string?
Sriram Venkataramani
|
|
|
|

|
Great article, appreciate you sharing your knowledge. OK, my question... about 3/4 the way down in your article you have this code:
...
string s = format.Trim().ToLower();
if (s.StartsWith("m"))
...
And then just below that you have this statement: "I could've just as easily used String.Compare, but if you supported multiple format specifiers you don't want the overhead of a case-insensitive string comparison in each condition."
I thought that a String.Compare with case-insensitivity was much faster than a ".ToLower()" call on a string (which creates a new string), and was created for the very purpose of avoiding such slow (memory allocating) calls.
Am I wrong? Should I be calling ToLower/ToUpper instead of String.Compare with case-insensitivity?
~Steve
|
|
|
|

|
If you look at the IL for String.StartsWith it does call String.Compare. Case-insensitive comparisons are typically as costly as making a string all lower- or upper-case. My comment about doing this once vs. calling String.Compare in a case-insensitive manner for every switch your formatter may support is true.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Customer Product-lifecycle Experience
Microsoft
[My Articles] [My Blog]
|
|
|
|

|
Ok, thanks! Just wanted to know, in case I was doing it the slow way in my own code...
~Steve
|
|
|
|

|
I have to provide an output for 3416 as 3.4K
If I need 3K it's easy: "0,K". What should I use in my case?
I'd prefer not to change the number itself dividing by 1000, just use the proper format.
Thank you!
zenit
|
|
|
|

|
Then you write an IFormatter that provides number formatting that devides the number for you. That's exactly what this article covers.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|

|
Thank you for your quick reply.
Actually me case is more complicated:
I have a method to define the format string:
public string GetFormat(double n) {
if (n > 999999999) return "0,,,G";
if (n > 999999) return "0,,M";
if (n > 999) return "0,K";
return String.Empty;
}
then I provide the output of the method to the Dundas software LabelStyle.Format property,
so I need a string. It worked fine but now I need one digit "after a decimal point", like 2.5G or 75.8K (it calculate bytes).
Is it possible to get a string that will convert 3416 to 3.4K ?
Thank you,
zenit
|
|
|
|

|
The default format provider for numeric types can already do that. For example:Console.WriteLine("{0:f1}M", 3416f / 1000);This is documented for the NumberFormatInfo class, as well as Single.ToString.
Be sure to use 3416f, otherwise you'll always get 3.0M. The reason is because you're dividing two integers. You need to use at least one float (System.Single) otherwise it will be rounded.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|

|
I've never really liked string formatting like this... it all seems rather archaic and orthogonal to the C# language. I mean, whey specify the formatting in a weird cryptic code hidden in the string when the formatting could be defined by the parameters to the ToString method in the parameters, and then just inserted like any other string.
Substitution is useful. {0} is useful. But anything else just seems like double the maintenance, unintuitive and damn-well mysterious! It almost certainly involves a trip to the documentation which I really dislike since intellisense came along.
That's just my opinion.
|
|
|
|

|
jmw wrote:
It almost certainly involves a trip to the documentation which I really dislike since intellisense came along.
You're entitled to your opinion, but if you hesitate to read the documentation, then you're shooting yourself in the foot and merely just writing code - something anyone can do.
Understanding takes research, and just relying on IntelliSense is not development - it's just writing code.
Microsoft MVP, Visual C#
My Articles
|
|
|
|

|
No sorry, I disagree with that.
Intellisense *is* documentation. It's documentation in a much better place, displayed in precisely the context where it is needed most.
And I don't understand why you imply that intellisense somehow detracts from understanding. It doesn't, it improves understanding because the information that you need to carry out the operation you are coding is right there in front of you, without the need to waste time looking up things on the web.
It's basically a matter of productivity.
The ToString() method is type safe, syntax checked, compiled code that provides intellisense and is thus far more readable and tells you exactly what it will do.
The format strings method is not type safe, is not syntax checked (until runtime in some cases, in other cases not at all), interpreted code, that for most people requires a trip to documentation to figure out what it is doing.
You see why I just don't get it?
|
|
|
|

|
No, it is not documentation. Documentation tells you all the information about a method, property, class, etc. Looking at the documetnation will also show you alternatives. And by reading the documentation (such as the class library documentation), you also become familiar with what's available rather than spend your time doing what the BCL has already provided. I spend a lot of time in the C# forum and see this all the time.
IntelliSense gives you summary information, as well as parameter information when you're currently filling a parameter - no remarks, no examples, no "See also", nothing.
ToString is used by the String.Format (and similar methods). If the type implements IFormattable, then it's implementation of ToString(string, IFormatProvider) is used. The same format specifiers for that ToString (or overloads, which typically call the IFormattable implementation) are the same as those for a formatting string. Take a little time and study how these methods work using ildasm.exe or something before you start knocking the differences. When it gets right down to it, there really are no differences becuase the same implementation is being used. The only real difference with using format specifiers in the format string is that they are parsed out and then passed to an IFormattable.ToString implementation.
Microsoft MVP, Visual C#
My Articles
|
|
|
|

|
I think most would agree that documentation isn't black or white, there are varying levels of documentation, intellisense providing one, help files providing another and books providing yet another. They're each useful.
For many who are familiar with the functioning of a class, intellisense is sufficient. Intellisense provides you with the list of options available for formatting a particular instance. It's the integration with the IDE that makes it most productive and attractive to the developer.
I know ToString may ultimately be used by Format -- I'm not talking about implementation, I'm talking about the interface to the user, and its integration with the compiler.
It's a fairly basic fact that compiled code runs faster, is subject to syntax and type checks and is just generally a better alternative to untyped interpreted code. In my mind, format strings are interpreted and don't go through any of these checks until runtime (if at all). (unless you're telling me that the compiler breaks down strings to look for things like that at compile time and optimizes accordingly? I doubt that, but I'm open).
When I have my developers write code, I want it to be as readable as possible. It's difficult enough remembering cryptic format string specifiers (just remembering those sscanf days), let alone when custom specifiers are introduced.
Code that calls functions with parameters is far easier to read and all-around produces more reliable code.
John
|
|
|
|

|
jmw wrote:
For many who are familiar with the functioning of a class, intellisense is sufficient.
Funny - I understand and know it well enough to not need an IDE and still program faster and better than most people.
The point is that most people don't know this environment at all. Hang out in the forums for a while and see the kinds of questions we get. "What's method X do?" "Why won't this work?" (no specifics given). Etc., etc.
jmw wrote:
It's difficult enough remembering cryptic format string specifiers (just remembering those sscanf days), let alone when custom specifiers are introduced.
I thought you said you're familiar with the Framework. I have no problem remember these, and if you expect to understand all the code in an entire application code base as you're scanning through, that's ludicrous. Sure, you can understand why a method uses the other classes in the GCL, but how all those types in your application relate to each other is another matter, unless you're an expert in your entire application's code base.
Argue about what you think documentation is all you want, but IntelliSense uses nothing more than tooltips and books are seldomly comprehensive like documentation (they're meant to teach concepts, unless you get the printed reference for the BCL and other similar books, of course).
jmw wrote:
Code that calls functions with parameters is far easier to read and all-around produces more reliable code.
That's a matter of opinion. I'd rather see a concise format string than a variable param list littered with "ToString". When developed correctly, the code is just as reliable as using the same format specifiers in ToString. Perhaps it's the developers who aren't reliable if they're getting it wrong.
Besides, as I already pointed out this makes localization much easier. Sure, you could achieve the same with indexers (minus the format specifiers) but what if you want to localize the format specifiers as well? You'd have to include localization code in each call to ToString, where I could localize the format string and be done with it.
If you don't like doing it this way, fine. It's your code.
Microsoft MVP, Visual C#
My Articles
|
|
|
|

|
Heath Stewart wrote:
When developed correctly, the code is just as reliable as using the same format specifiers in ToString. Perhaps it's the developers who aren't reliable if they're getting it wrong.
That's my whole point. Format strings are more prone to error and mistakes because of lack for support in the IDE and by the compiler. Any errors you make in the syntax of a ToString call will be picked up during compilation.
I'm sorry but to say 'perhaps it's the developers who aren't reliable' is so arrogant. All developers make mistakes, unless you're telling me you've never got a compilation error in your life?
Heath Stewart wrote:
Besides, as I already pointed out this makes localization much easier.
I don't see how, implementations of ToXXXString methods should be culture aware anyway.
|
|
|
|

|
jmw wrote:
I'm sorry but to say 'perhaps it's the developers who aren't reliable' is so arrogant. All developers make mistakes, unless you're telling me you've never got a compilation error in your life?
Of course I've made mistakes - as you say, everone does. But see, there's a little thing me and other people called "testing", where problems like this come out.
jmw wrote:
I don't see how, implementations of ToXXXString methods should be culture aware anyway.
Most are, but do you expect there to be defined a ToXXXString for every format specifier available? Just take a look at the DateTime struct. It has a few such methods but many more specifiers. Besides, the interfaces and implementations of IFormattable, IFormatProvider, and ICustomFormatter all work together to provide an abstract programming model. I suppose you don't like those, either?
Besides, why don't you use the IL Disassembler to take a look at those ToXXXIString implementations. I think you'll find most (if not all in the BCL) simply call the IFormattable.ToString implementation. At least that's what I've seen in the 1.x BCL assemblies and do in our product, as well as having seen that in other products.
Microsoft MVP, Visual C#
My Articles
|
|
|
|

|
Heath Stewart wrote:
Most are, but do you expect there to be defined a ToXXXString for every format specifier available? Just take a look at the DateTime struct.
Actually the DateTime struct is a bad example as I think they've done a poor job of exposing the formatting functions. An overloaded ToString function that has separate parameters to indicate the various elements of the resultant string would be preferable. I certainly think that should be the way any custom formatting functions should be defined.
Heath Stewart wrote:
Besides, the interfaces and implementations of IFormattable, IFormatProvider, and ICustomFormatter all work together to provide an abstract programming model. I suppose you don't like those, either?
Er and why do you suppose that. I don't see what abstract programming models have to do with this. Other than the fact there's nothing abstract about a formatting string whatsoever. I do love high level, object oriented designs and APIs, and perhaps that's why I don't like format strings.
Don't get me wrong -- I'm a great believer in the right tool for the right job, and I believe people should use different, domain specific languages where it's more suitable and helps productivity.
Take for example regular expressions. They suffer from the same problem of having no compiler support, yet regular expressions certainly do cut down on the verbosity of the equivalent C# code.
This is really an IDE issue, and isn't an argument for one use over another. If the IDE understood sub-languages in C# code, and could provide various compile time checks, then this wouldn't be so much of an issue, and maybe it could even provide drop-down intellisense when you insert that '{' in the string.
In the meantime, I'm going to stick to using C#.
John
|
|
|
|

|
jmw wrote:
Er and why do you suppose that. I don't see what abstract programming models have to do with this. Other than the fact there's nothing abstract about a formatting string whatsoever. I do love high level, object oriented designs and APIs, and perhaps that's why I don't like format strings.
What do you think this article was about? Without the support for the interfaces I mentioned, none of this would be possible. String.Format, StringBuilder.AppendFormat, TextWriter.WriteLine, etc. would never work. There is an abstract model here using the interfaces like IFormatProviders and the like, without which localization wouldn't be possible in .NET, since that's what the string formatting methods use to output localized (for a region, not necessarily a culture which is the job of other interfaces in System.Globalization and System.Resources) text. You might try reading about these various interfaces to see how they all work together, and even examine a few things like those various ToString methods (and DateTime's not the only struct that uses what I mentioned) and see how they work.
jmw wrote:
This is really an IDE issue, and isn't an argument for one use over another. If the IDE understood sub-languages in C# code, and could provide various compile time checks, then this wouldn't be so much of an issue, and maybe it could even provide drop-down intellisense when you insert that '{' in the string.
Perhaps, but that information isn't provided by the CLI implementation. It's a documentation feature only. A new documentation syntax would need to be defined, not that that's impossible (I'm on the NDoc[^] team and we're currently working with Microsoft on that for a standard platform support syntax).
There nothing that says a format string doesn't belong in an object-oriented environment. String I/O is one of the most basic attributes of computer programming, whether it's procedural or object-oriented. It sure beats printf et. al. as I mentioned in my articles, and is still very flexible. If you don't like reading the documentation in order to leverage this powerful feature, that's your prerogative.
Microsoft MVP, Visual C#
My Articles
|
|
|
|

|
Heath Stewart wrote:
What do you think this article was about? Without the support for the interfaces I mentioned, none of this would be possible.
Yes but that's implementation! I'm not talking about implementation! I'm talking about how the developer *uses* the features, and how the features integrate with the environment. I'm sure the implementation model is just wonderful.
Heath Stewart wrote:
Perhaps, but that information isn't provided by the CLI implementation.
I haven't thought about it that much, but I'm thinking it's possible to achieve some degree of support in the CLI through attributes on methods.
In a sense format specifiers are parameterized instantiation commands, just written in the 'format string' language. So in that sense, format strings conform to a declarative language of sorts, and looking at XAML and BAML it's quite clear that declarative languages are fully supportable by the CLI.
So I think there *is* room for better integration with languages such as format strings (and regex) with the IDE. It's probably just a matter of time.
And, like I said, once there's an IDE for the language, it'll be more appealing to me, and to others.
John
|
|
|
|
|
|

|
Interesting. I also just figured that if the man pages say so, it must be true! I do know that using "PERL" is incorrect, but I figured it was just because it is common enough to use "Perl" instead. I will update my article.
Microsoft MVP, Visual C#
My Articles
|
|
|
|

|
It wasn't really a nitpick, I just stumbled across that page the other day and found it interesting. I'd never even heard of "Pathologically Eclectic Rubbish Lister", but thought it was kinda funny.
Regards,
Jeff Varszegi
EEEP! An Extensible Expression Evaluation Package
|
|
|
|

|
Hi Heath,
Great article. One point I'd add is the importance of indexed format specifiers to creating internationalized code. This is because the grammar of various languages may make it important to reverse the order of sentence components. Since the original printf() format specification didn't support indexers, internationalization was not really possible. The nice thing about string.Format() is that you are forced (in a nice and natural way) to reference the arguments by index, so internationalization becomes just a matter of putting the strings into resources and localization becomes relatively simple.
Tom Clement
Apptero, Inc.
|
|
|
|

|
A little off-topic, but since you seem to be no stranger to localization, .NET 2.0 features the ComponentResourceManager which makes localization of a project much easier.
I was just browsing through some stuff today in VS.NET 2005 on my other partition and noticed that my ResX file (when testing some localization stuff) wasn't nearly as big. In .NET 1.x, we never localized our apps because anything with LocalizableAttribute set to true incurs additional calls to get information from the embedded resource. This was not acceptable.
.NET 2.0 introduces and uses the ComponentResourceManager which enumerates the resources, caches them for the object's lifetime, and matches up properties based on a root name for a control and assigns them. This performs much better than using a ResourceManager which must know names up front, and allows developers to localize an application or library without littering code with ResourceManager.GetObject calls for every localizable property!
I'm currently planning a write-up on localization and plan on mentioning some of this. I know it's early, but I think this is a cool feature and have yet to see any MSDN articles on that (they're all about C# language enchancements, generics, and Indigo lately it seems).
Just thought you might like to know.
Microsoft MVP, Visual C#
My Articles
|
|
|
|

|
Thanks Heath,
I haven't been able to keep up with what's going on with .NET 2.0, so it's great to hear about the ComponentResourceManager. Thanks for the summary! I look forward to your write-up.
Tom Clement
Apptero, Inc.
My articles[^]
|
|
|
|

|
Do you happen to know how to handle collection localization using ComponentResourceManager.
ApplyResources doesn't seem to cover localizing item collections.
|
|
|
|
|

|
A @-quoted string is a literal. To put line-breaks into it, you actually put a line break in the string like:string s = @"This sentence
is broken."; If you see this in the debugger windows, don't worry about it. The information you see there is typically encoded wrong and will be improved in VS.NET 2005.
The fact of the matter is that "@" is only a compile-time directive, so any strings you get programmatically at runtime won't be affected.
I just tried it myself with no problems:using System;
using System.Resources;
public class Test
{
static void Main()
{
ResourceManager resources = new ResourceManager(typeof(Test));
Console.WriteLine(resources.GetString("Test"));
System.Windows.Forms.MessageBox.Show(resources.GetString("Test"));
}
}
Test = This is\na test.
Build:
resgen Test.txt Test.resources
csc /t:exe /res:Test.resources Test.csGot breaks in both the console and the message box.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|

|
You can use str.Replace(@"\n","\n");
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.
|
Discusses the implementation of custom format providers for existing types and custom formatting for user-defined types.
| Type | Article |
| Licence | Ms-PL |
| First Posted | 26 Mar 2004 |
| Views | 322,230 |
| Bookmarked | 111 times |
|
|