I'm wondering something. Instead of writing String.Format("{0:X}", num); to convert numbers to hex. Is there a way where i could extend string directly so that i could simply write num.ToHex(); instead?
You can create extension method:
public static class IntExtensions
{
public static string ToHex(this int source)
{
return string.Format("{0:X}", source);
}
}
Execute like this:
string hexNum = 1234.ToHex();
It's called extension method. However, it should be set on numeric type, to allow {0:X} string format:
public static class Extensions
{
public static string ToHex(this int source)
{
return string.Format("{0:X}", source);
}
}
Related
I have a class that implements IFormattable and I want to also implement ISpanFormattable as defined in C# 7
public partial interface ISpanFormattable : System.IFormattable
{
bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider? provider);
}
Here is the implementation that I came up with, but I am not sure if this follows the logic it is intended to have. I am unclear about when to return true/false and how to handle the arguments correctly.
public class Foo : ISpanFormattable
{
// other definitions
#region Formatting
public override string ToString() => ToString("g");
public string ToString(string? formatting) => ToString(formatting, CultureInfo.CurrentCulture.NumberFormat);
public string ToString(string? formatting, IFormatProvider? formatProvider)
{
// code to return a formatted string
}
public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider? provider)
{
string formatting = format.ToString();
string result = this.ToString(formatting, provider);
charsWritten = Math.Min(result.Length, destination.Length);
result.CopyTo(destination[..charsWritten] );
return charsWritten == result.Length;
}
#endregion
}
What I have done is convert the ReadOnlySpan<char> format into a string in order to call the existing ToString() function, and then use the result to copy into the destination. The function will return false if the resulting string is larger than the destination Span<char>.
It seems a bit long for a basic wrapper around ToString(), and might be a performance bottleneck when converting Span<char> to string.
Is there a simpler/better way to implement TryFormat() for my class?
In Java we can use methods in enums, for example i can write
public static void main(String []args){
System.out.println(GetNum.TWO.get());
}
enum GetNum{
ONE{
public int get(){
return 1;
}
},
TWO{
public int get(){
return 2;
}
};
public abstract int get();
}
maybe somebody can say me: in c# enums can I do something like this?
Not really, but you can sort of though the use of extension methods.
Given an enumeration such as
enum HurfDurf
{
Hurr,
Durr
}
you can create an extension method such as
static class HurfDurfExtensions
{
public static string Wat(this HurfDurf lol)
{
return lol == HurfDurf.Hurr ? "Wew lad" : "eyy boss";
}
}
and use it like
var whatisthisidonteven = HurfDurf.Hurr.Wat();
No you can't. In the background enum are value-types (e.g. just an int).
E.g. you can do int i = (int)yourEnum;and vice versa.
I have the simple method below:
public static bool IsErrorMessage(String error)
{
var isErrorMessage = error.Left(40).Contains("ErrorMessage",StringComparison.CurrentCulture);
return isErrorMessage;
}
But I getting an error that says string does not contain a definition for 'Contains' and VS wants to use System.Linq.Enumerable.Contains instead.
Using .NET Framework 4.5, C#, VS 2010 and of course I have a using System directive.
There is no overload of String.Contains that takes two arguments. If you want to use a StringComparison, use IndexOf:
bool isErrorMessage = error.Left(40).IndexOf("ErrorMessage", StringComparison.CurrentCulture) > -1;
Looks like it's preferring the LINQ extension method due to the two parameters, since String::Contains only has one param.
I think you need to flesh out your extension methods to discover the problem. Here is a compiling example that should get you started:
public static class StringExtensions
{
public static string Left(this string s, int count)
{
// your method
return "";
}
public static bool Contains(this string s, string contains, StringComparison comp)
{
// your method
return true;
}
}
public class Test
{
public static bool IsErrorMessage(String error)
{
var isErrorMessage = error.Left(40).Contains("ErrorMessage", StringComparison.CurrentCulture);
return isErrorMessage;
}
}
I need to create an extension method to array class, but this extension method must be able to accept many data types, so it also must be generic.
In the code bellow the extension method just accept byte data type. I want it to also accept ushort and uint for instance.
I believe that the best way to do that is creating a generic type here. But how can I do that using arrays?
Thanks!!!
public static class MyExtensions
{
public static int GetLastIndex(this byte[] buffer)
{
return buffer.GetUpperBound(0);
}
}
Generics in extension methods aren't really anything special, they behave just like in normal methods.
public static int GetLastIndex<T>(this T[] buffer)
{
return buffer.GetUpperBound(0);
}
As per your comment, you could do something like the following to effectively restrict the type of T (adding guard statements).
public static int GetLastIndex<T>(this T[] buffer) where T : struct
{
if (!(buffer is byte[] || buffer is ushort[] || buffer is uint[]))
throw new InvalidOperationException(
"This method does not accept the given array type.");
return buffer.GetUpperBound(0);
}
Note: As Martin Harris pointed out in a comment, you don't actually need to use generics here. The Array type from which all arrays derive will suffice.
If you want a more elegant solution, at the cost of slightly more code, you could just create overloads of the method:
public static int GetLastIndex(this byte[] buffer)
{
return GetLastIndex(buffer);
}
public static int GetLastIndex(this ushort[] buffer)
{
return GetLastIndex(buffer);
}
public static int GetLastIndex(this uint[] buffer)
{
return GetLastIndex(buffer);
}
private static int GetLastIndex(Array buffer)
{
return buffer.GetUpperBound(0);
}
public static class MyExtensions
{
public static int GetLastIndex<T>(this T[] buffer)
{
return buffer.GetUpperBound(0);
}
}
Same way you do generics in normal (non-extension) methods: Use a placeholder type name introduced in the generic syntax:
public static int GetLastIndex<TElement>(this TElement[] buffer)
#RHaguiuda
You can make constraint like
public static class MyExtensions{
public static int GetLastIndex<T>(this T[] buffer) where T: Integer
{
return buffer.GetUpperBound(0);
}}
But, type used as a constraint must be an interface, a non-sealed class or a type parameter
Consider the following code:
public class TextType {
public TextType(String text) {
underlyingString = text;
}
public static implicit operator String(TextType text) {
return text.underlyingString;
}
private String underlyingString;
}
TextType text = new TextType("Something");
String str = text; // This is OK.
But I want to be able do the following, if possible.
TextType textFromStringConstant = "SomeOtherText";
I can't extend the String class with the TextType implicit operator overload, but is there any way to assign a literal string to another class (which is handled by a method or something)?
String is a reference type so when they developed C# they obviously had to use some way to get a string literal to the class. I just hope it's not hardcoded into the language.
public static implicit operator TextType(String text) {
return new TextType(text);
}
Add
public static implicit operator TextType(string content) {
return new TextType(content);
}
to your class? :)