How to Extend C# Built-In Types, Like String

How to extend C# built-in types, like String?

Since you cannot extend string.Trim(). You could make an Extension method as described here that trims and reduces whitespace.

namespace CustomExtensions
{
//Extension methods must be defined in a static class
public static class StringExtension
{
// This is the extension method.
// The first parameter takes the "this" modifier
// and specifies the type for which the method is defined.
public static string TrimAndReduce(this string str)
{
return ConvertWhitespacesToSingleSpaces(str).Trim();
}

public static string ConvertWhitespacesToSingleSpaces(this string value)
{
return Regex.Replace(value, @"\s+", " ");
}
}
}

You can use it like so

using CustomExtensions;

string text = " I'm wearing the cheese. It isn't wearing me! ";
text = text.TrimAndReduce();

Gives you

text = "I'm wearing the cheese. It isn't wearing me!";

Is there a way to extend a built-in type to inherit an interface?

UPDATED (ADD MORE EXPLANATION)

As requested, I want to explain a bit more about my last answer.

Requirements

  • The Conclusion need to support both value type and reference type
  • Generic
  • Value Types: all numeric data types (int, short, long, etc), boolean, char, date....
  • Reference Types: string and user-defined class (in OP's sample, IConcludable)

Solution:

  • Introduce a base class (AbstractConclusion) that accepts Object as generic input
  • Move the logic to base class for reuse
  • Introduce two new concrete implementations that accepts struct and IConcluable (have the ability to add more implementation, for ex: string)
  • The inherited classes are able to all the methods of base class

ORIGINAL ANSWER:

You can put the logic in AbstractConclusion class, and have two implementations of it (Conclusion which accepts IConcludeable and PrimitiveConclusion which accepts struct data type)

See code sample below:

void Main()
{
PrimitiveConclusion<int> primitiveConclusion = new PrimitiveConclusion<int>(1);
Conclusion<ParseResult> parseResultConclusion = new Conclusion<ParseResult>(new ParseResult {});

Console.WriteLine($"{primitiveConclusion.Result.GetType()}");
Console.WriteLine($"{parseResultConclusion.Result.GetType()}");
}

public class TestClass
{
public Conclusion<ParseResult> ParseInput(string input)
{
return new Conclusion<ParseResult>(null);
}
}

public interface IConcludable { }

public abstract class AbstractConclusion<T>
{
public AbstractConclusion(T t)
{
IsSuccessful = t != null;
Result = t;
}
public bool IsSuccessful;
public T Result;
}

public class Conclusion<T> : AbstractConclusion<T> where T : IConcludable
{
public Conclusion(T t) : base(t)
{
}
}

public class PrimitiveConclusion<T> : AbstractConclusion<T> where T : struct
{
public PrimitiveConclusion(T t) : base(t)
{
}
}

public class ParseResult : IConcludable { }

How to create extension methods for Types

The short answer is it cannot be done; extension methods need to work on an instance of something.

How to Extend the Type Class

You can't have static extension methods. Your extension method works on an instance of the Type class, so to call it you'd have to do something like this:

typeof(Type).IsBuiltIn("System.Int32")

The workaround for this is to just put your extension method in a utility class, e.g. like the following, and call it like a normal static function:

public static class TypeExt
{
public static bool IsBuiltIn(string _type)
{
return Type.GetType(_type) == null;
}
}

// To call it:
TypeExt.IsBuiltIn("System.Int32")

By the way, I don't think this will tell you whether the type is "built-in"; it will merely tell you whether a type with the given name has been loaded into the process.

I would like to add a string extension method. But where should I add that in my Xamarin Forms application so it's available everywhere?

This, in fact, would be an int extension method. It needs to be static; also, in order for it to be accessible everywhere, it needs to be public. Extension methods need to be defined in a static class, and they should contain the keyword this before the first argument, which would be indicating the type to extend. So the final approach would be:

namespace YourNameSpace
{
public static class Int32Extensions
{
public static string S(this int i)
{
return i == 1 ? "" : "s";
}
}
}

To use it somewhere else, you need to use the namespace in your subject code file

using YourNameSpace;

And simply call it

int i = 3;
string str = i.S(); //equals "s"

Extending primitive types

You cannot extend them directly - the String class is sealed, for example, and as you noted value type wrappers (such as Int32) are normally structs.

You can write extension methods (C#, VB.NET) to them, that's what they are there for.

Another option, is to write a wrapper around these, exposing all of their properties and adding more functionality.

Should I extend the system types, or just create a static utility class? How do I know when to do which?

How do you know when to just extend a method versus creating a static helper class?

The two are basically the same - it's more of how you expect and want the items to be used.

My general rule of thumb is: Will this method be something every developer would (potentially) want to use on every single string or string[] instance? If so, consider an extension method. If not, use a normal static method.

In this case, it seems like the use case is very narrow, and not appropriate to an arbitrary string instance, which would suggest a normal, static helper method. This is almost always the case for core built-in types (object/string/etc), since it's very rare that a method is really appropriate for all uses of the type.

Also: Note that this doesn't extend the type, it merely provides a different syntax for accessing your static method.

Possible to extend the String class in .net

The String class is sealed so you can't inherit from it. Extension methods are your best bet. They have the same feel as instance methods without the cost of inheritance.

public static class Extensions {
public static bool contains(this string source, bool ignoreCase) {... }
}

void Example {
string str = "aoeeuAOEU";
if ( str.contains("a", true) ) { ... }
}

You will need to be using VS 2008 in order to use extension methods.

C# Extension Method that reads an object as a specified type

I think it's OK if your program needs it but I'd like to make a few style suggestions:

  • call it Convert<T> rather than As<T>
  • let the defaultValue take a default
  • Consider not making it be an extension method. I know extension methods are great and all but I think there's something overly promiscuous about extension methods whose first argument is System.Object. The problem is you hit the autocomplete key in your IDE and you start finding a bunch of weird extension methods on every single object you use in your program. Converting isn't that common an operation, so I think I'd prefer MyUtil.Convert

So I'd slightly change your signature at least to:

public static class MyUtil {
public static T Convert<T>(object instance, T defaultValue=default(T))

* EDIT *

I might also propose the alternative syntax

public static bool TryConvert<T>(object instance, out T result) {

* EDIT 2 *

And I might propose taking IConvertible rather than object, just to narrow the interface a little bit:

  public static T Convert<T>(IConvertible instance, T defaultValue=default(T)) {
...
}
public static bool TryConvert<T,U>(T instance, out U result) where T : IConvertible {
...
}


Related Topics



Leave a reply



Submit