Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I apply the same extension to many classes without copy paste?

Let's say I have this extension for CGFloat

extension CGFloat {
    // common 
    public var thrice: CGFloat { return self * 3.0 }
    public var twice: CGFloat { return self * 2.0 }
    public var half: CGFloat { return self * 0.5 }
    public var third: CGFloat { return self / 3.0 }
    public var fourth: CGFloat { return self * 0.25 }
    public var sixth: CGFloat { return self / 6.0 }
    public var eighth: CGFloat { return self * 0.125 }
    public var twelfth: CGFloat { return self / 12.0 }
    public var sixteenth: CGFloat { return self * 0.0625 }

    //
    public var inverse: CGFloat { return 1.0 / self }
}

What I want to do is have these apply to CGFloat, Double and Float without having to copy/paste the code. Is this at all possible?

Thanks!

like image 666
JP. Avatar asked Jul 26 '14 02:07

JP.


People also ask

Can extension methods extend non static classes?

It is compulsion that the Extension method must be in a Static class only so that only one Instance is created. For example, if you place the following in ASP.Net page it will not work. Though error will not come, but you will not see the method available. The above will not work.

Is it possible to add extension methods to an existing static class?

No. Extension methods require an instance variable (value) for an object.

Can you add extension methods to an existing static class C#?

In C#, the extension method concept allows you to add new methods in the existing class or in the structure without modifying the source code of the original type and you do not require any kind of special permission from the original type and there is no need to re-compile the original type.

Why extension methods are static?

Essentially, an extension method is a special type of a static method and enable you to add functionality to an existing type even if you don't have access to the source code of the type. An extension method is just like another static method but has the “this” reference as its first parameter.


1 Answers

You cannot do it by extending the types (all at once), but you could do it using templated functions:

protocol FloatLiteralMultipliable: FloatLiteralConvertible {
    func *(lhs: Self, rhs: Self) -> Self
    func /(lhs: Self, rhs: Self) -> Self
}

extension Float: FloatLiteralMultipliable {}
extension CGFloat: FloatLiteralMultipliable {}
extension Double: FloatLiteralMultipliable {}

func thrice<T: FloatLiteralMultipliable>(value: T) -> T { return value * 3.0 }
func twice<T: FloatLiteralMultipliable>(value: T) -> T { return value * 2.0 }
func half<T: FloatLiteralMultipliable>(value: T) -> T { return value / 2.0 }
func third<T: FloatLiteralMultipliable>(value: T) -> T { return value / 3.0 }
func fourth<T: FloatLiteralMultipliable>(value: T) -> T { return value / 4.0 }
func sixth<T: FloatLiteralMultipliable>(value: T) -> T { return value / 6.0 }
func eighth<T: FloatLiteralMultipliable>(value: T) -> T { return value * 0.125 }
func twelfth<T: FloatLiteralMultipliable>(value: T) -> T { return value / 12.0 }
func sixteenth<T: FloatLiteralMultipliable>(value: T) -> T { return value / 0.0625 }

func inverse<T: FloatLiteralMultipliable>(value: T) -> T { return 1.0 / value }

thrice(Float(10.0)) // 30.0
half(CGFloat(2)) // 1.0
inverse(Double(1.0/10.0)) // 10.0

Note: I am only explicitly constructing the types in my example calls to prove that it the functions can be used with each of the types

like image 156
drewag Avatar answered Sep 18 '22 21:09

drewag