Extensions in My Own Custom Class

Extensions in my own custom class

In the case of a class that you create from scratch extensions are a powerful type of documentation through structure. You put the core of your class in the initial definition and then add on extensions to provide additional features. For example, adding adherence to a protocol. It provides locality to the contained code:

struct Foo {
let age: Int
}

extension Foo: CustomStringConvertible {
var description:String { return "age: \(age)" }
}

Could I have put the protocol and computed property in the struct declaration? Absolutely but when you have more than one or two properties it starts to get messy and difficult to read. It's easier to create bugs if the code isn't clean and readable. Using extensions is a great way to stave off the difficulties that come with complexity.

Extension Methods with Custom Classes

Extension methods require an instance of an object. You'll have to new up a CustomClass to use it.

var custom = new CustomClass();
custom.DoSomething();

See this answer as to why that is.

How to create custom extension method for a custom class?

You need to cast SelectedItem to ComboBoxItem, then access it's Value property :

var i = ((ComboBoxItem)sTD_PROVINCEComboBox.SelectedItem).Value;

With that i will contain the Value, so in the foreach you can simply do as follow :

foreach(var item in UE2.Cities.Where(x => x.CITY_PROVINCE_ID == i)

UPDATE :

Just notice that Value property of ComboBoxItem is of type object (I was assuming it is int). If this is the case, the above foreach part won't compile (comparing int with object is not allowed). Assuming CITY_PROVINCE_ID is of type int, and i storing boxed int you'll need to unbox i back to int :

foreach(var item in UE2.Cities.Where(x => x.CITY_PROVINCE_ID == (int)i)

Why does my custom class not recognize swift extensions? (i.e. String)

How did you add the class with the extension? I added some classes into my project which included extensions, and the rest of the code wouldn't recognize the extensions. It appears that this was because I had added the files using "Create folder references" option instead of "Create groups" option. I deleted what I had added, then added them again with "Create groups" option selected. This fixed it for me.

I'm didn't pursue why using references might result in this behavior, because I had intended to add them with the "Create groups" option to begin with.

Creating an extension to a class?

As Oli mentions, it is not possible.

It is worth mentioning that an extension method in C# is just a fancy way of calling an Static method, so although it looks like

someobject.MyExtensionMethod();

then the compiler translates that to

SomeStaticClass.MyExtensionMethod(someobject);

You are not really adding a method to the object

Add static method to current custom class

That's an extension method and those need to go in a static class. If you want to just make it work in your existing non-static class, just get rid of the this on the first parameter:

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr w, IntPtr l);

public static void SetState(ProgressBar pBar, int state)
{
SendMessage(pBar.Handle, 1040, (IntPtr)state, IntPtr.Zero);
}

The parameter can still be of type ProgressBar since CustomProgressBar inherits from it.

How do I use extensions to extend an object's tableview's functionality from the calling class?

For this specific example...

Add a property to your CustomClass:

class CustomClass: UIView {

// this may be changed by the "calling class"
var numRows: Int = 10

@IBOutlet weak var abtn: UIButton!
@IBOutlet weak var table: UITableView!

func setupTable(){
table.delegate = self
table.dataSource = self

table.register(UITableViewCell.self, forCellReuseIdentifier: "cellId")
table.backgroundColor = UIColor.black.withAlphaComponent(0.1)
}
}

In your extension, use that property:

extension CustomClass: UITableViewDelegate, UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// don't make this a hard-coded number
//return 10
return numRows
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = table.dequeueReusableCell(withIdentifier: "cellId", for: indexPath)

return cell
}
//And more stuff that is not useful rn
}

Then, in your "calling class", you can change that property:

class ExampleViewController: UIViewController {

let myView = CustomClass()

override func viewDidLoad() {
super.viewDidLoad()

view.addSubview(myView)
// constraints, etc

// change the number of rows in the table in myView
myView.numRows = 20
}

}

More likely, though, you would be doing something like setting / changing the data for the table in your custom class.

Here's an example, along with showing how to use a closure to "call back" to the calling class / controller:

class CustomClass: UIView {

// this may be changed by the "calling class"
var theData: [String] = []

// closure to "call back" to the controller
var callback: ((IndexPath) -> ())?

@IBOutlet weak var abtn: UIButton!
@IBOutlet weak var table: UITableView!

func setupTable(){
table.delegate = self
table.dataSource = self

table.register(UITableViewCell.self, forCellReuseIdentifier: "cellId")
table.backgroundColor = UIColor.black.withAlphaComponent(0.1)
}
}
extension CustomClass: UITableViewDelegate, UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return theData.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = table.dequeueReusableCell(withIdentifier: "cellId", for: indexPath)
cell.textLabel?.text = theData[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// tell the controller the cell was selected
callback?(indexPath)
}
}

class ExampleViewController: UIViewController {

let myView = CustomClass()

override func viewDidLoad() {
super.viewDidLoad()

view.addSubview(myView)
// constraints, etc

// set the data in CustomClass
myView.theData = [
"First row",
"Second row",
"Third",
"Fourth",
"etc..."
]

myView.callback = { indexPath in
print("CustomClass myView told me \(indexPath) was selected!")
// do what you want
}
}

}

In Typescript, create extension method for class that from library

Ok, I reference to this answer and solve my question with the following code.

In polyfill.ts

import {Page} from 'ionic-angular/navigation/nav-util';
// the class we wanna create extension method
import {NavController} from 'ionic-angular/navigation/nav-controller';
// ionic provide this as NavController
import {NavControllerBase} from 'ionic-angular/navigation/nav-controller-base';

// add extension method on both class via interface
declare module "ionic-angular/navigation/nav-controller" {
interface NavController {
// replacePage?: typeof replacePage;
replacePage(page: Page, data?: any);
}
}
declare module "ionic-angular/navigation/nav-controller-base" {
interface NavControllerBase {
// replacePage?: typeof replacePage;
replacePage(page: Page, data?: any);
}
}

// define extension method
function replacePage(this: NavController, page: Page, data?: any): Promise<any> {
return this.push(page, data).then(() => {
let index = this.getActive().index;
this.remove(index - 1);
});
}

// finally add this function to the class that ionic provide
NavControllerBase.prototype.replacePage = replacePage;

usage:

constructor(private navCtrl: NavController)
foo(){
this.navCtrl.replacePage(HomePage, {nextPage: OtherPage});
}

This way to add extension method on other class, wish this help someone after.

What is the best way to create custom extension methods for VS UT Assert class?

If you are referring to this Assert class, then you cannot add extension methods. Extension methods can only be applied to object instances. Since this class is static, it can never be instantiated.

You could add your own custom Assert type class like so though:

public static class MyAssert {
public static void AreEqual(object expected, object actual) {
// TODO: throw if not equal
}
}


Related Topics



Leave a reply



Submit