简体   繁体   中英

Write an extension method for generic type

I need to write an extension method in order to replace a char in a string and in a StringBuilder. I can write two extension methods like:

public static string ReplaceChar(this string value, string charToReplace)
{
    return value.Replace(charToReplace, "_");
}

public static StringBuilder ReplaceChar(this StringBuilder value, string charToReplace)
{
    return new StringBuilder (value.ToString().Replace(charToReplace, "_"));
}

But I don't know if there is the possibility to write a generic method like:

public static T ReplaceChar<T>(this T value, string charToReplace)
{
    return new T(value.ToString().Replace(charToReplace, "_"));
}

In this case I have an error: T does not have a new() constructor

it is a very bad idea. You want to use an immutable type and a mutable type in the same way. The sole role of a StringBuilder is to offer better speed performance for string operations. Your StringBuilder extension method is awful and useless.

  • Awful because it creates 2 objects and is against StringBuilder philosophy.
  • Useless because StringBuilder already has a Replace method

There are two problems with your approach. The one giving you the error is that T needs to have a new() constraint if you want to new it:

public static T ReplaceChar<T>(this T value, string charToReplace)
     where T : new()

The second problem is that the constraint only says it has a constructor without parameters, you can't call a constructor with parameters... so:

return new T(value.ToString().Replace(charToReplace, "_"));

Is just not possible, it's a limitation of generics (you can't make a constraint of new(string) or anything similar). Would probably be a nice feature and you can suggest it :-)

So about your specific question, it's not possible to do what you want: string and StringBuilder are two completely different types, which don't share any useful interface, and no useful constraint that may let you use both in a generic method (be it an extension method or not). You are down to implement both extension methods for this specific case.

About the question title ( "Write an extension method for generic type" ), yes, it's possible to have such an extension method with generics, and it'll work for all types that meet the constraints of T . It doesn't make much sense without specific constraints (like interfaces) since you won't be able to basically do anything with the object... and if you are not using constraints, you'd be better off making an extension method of object .

The only thing that comes to mind where this might be useful, is if trying to make an extension method of a type that requires the same type to be passed as an additional parameter... something like:

public static int Compare<T>(this T value, T value2)
    where T : IComparable
{
    return value.CompareTo(value2);
}

Where you want to make sure that the second parameter is of the same type that the extended object.

Unfortunately, there is no simple way you can achieve this

You cannot use any constructor that takes parameters from generics. They are limited purely to "new T()'.

You can get around this using reflection, but it will render your code difficult to understand and prevent compile-time type checking.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM