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!
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.
No. Extension methods require an instance variable (value) for an object.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With