= Porting C# code to Cobra = see [wiki:C#Diffs Cobra differences fm C#] Heres a process for C# to Cobra generally. 1. Take .cs file, rename to .cobra file. 2. Change multiline comments from multiple // or /* */ bounded to be /# #/ bounded.[[br]] Change single line comments to use leading ''''#'''' Remove extraneous separator line comments between method calls - if any {{{ // ------------------------------ }}} 3. Remove trailing '''';'''' from each line they occur on 4. Fixup blocking and indentation. Remove all '{' and '}' indicating start and end blocks from source.[[br]] Ensure remaining blocks are all correctly (equally) indented and that indentation uses either all spaces or all Tabs and that the indents are in multiples of either 4 spaces or 1 tab. 5. Fix 'using' statements: [[br]] '''using''' -> '''use''' [[br]] Remove any lines for {{{ using System using System.Collections.Generic using System.IO using System.Text }}} as cobra includes these automagically Change any other lines from ''''using xxxx;'''' to ''''use xxxx'''' 6. Namespace decl Namespaces in cobra need to start with an upcased letter. [[BR]] Remove any lowercased prefix from namespace line 7. Correct any Enum definitions. [[br]] After applying the above its basically removing trailing ',' and ensuring indentation of enum items are all the same. e.g. {{{ enum ID_CONTROLS { ID_RADIO_ORIENT = 5999, ID_CHK_SHOWIMAGES, ID_BTN_NEXT_PAGE, ID_NOTEBOOK } }}} to {{{ enum ID_CONTROLS ID_RADIO_ORIENT = 5999 ID_CHK_SHOWIMAGES ID_BTN_NEXT_PAGE ID_NOTEBOOK }}} 8. Fix class declaration syntax Change lines like ''''class X : Y'''' to ''''class X inherits Y'''' 9. Change any class instance attributes/fields to be prefixed with ''''var'''' Change type and accessmodifier to cobra forms {{{ name = ; }}} to {{{ var name as = }}} 10. Fixup class constructor definitions For initializer/constructor change lines like : {{{ public ClassName(params,...) : base(baseParams,...) }}} to {{{ cue init(params, ...) is public base.init(baseParams,...) }}} Within the params list correct type declaration syntax from C# to cobra {{{ [ ...] name, }}} to {{{ name as [is , ...], }}} public is default accessModifier so can leave that off[[br]] e.g. {{{ public GeoArea (string title, GeoPoint pos, Size size) : base(title, pos, size) }}} to {{{ cue init(title as String, pos as GeoPoint, size as Size ) is public base.init (title, pos, size) }}} 11. Remove any uses of ''''new'''' to construct a class instance, instead just make a call to the class type passing any initializer args, i.e just remove 'new'[[br]] e.g. {{{ var gFile = new GeoFile() -> gFile = GeoFile() new GeoPoint(10, 100) -> GeoPoint(10, 100) new Size(650,340) -> Size(650, 340) }}} For classes that construct delegates (take method names) prefix the methodname with '''ref''', methodNames must start with a lowercase letter and are prefixed by ''''this.'''' or just ''''.'''' so change the methodName accordingly e.g. {{{new Listener( OnFileChange ) -> Listener(ref .onFileChange) }}} 12. Methods: Prefix methods with '''def'''.[[br]] Change methodnames to start with a lowercase letter, [[br]] Change param definitions to cobra form.[[br]] {{{[ ...] name,}}} -> {{{name as [is , ...],}}} Cobra methods by default return void and are public so if the C# code specifies '''public void''' you can just delete those words. Also, if a method has no parameters then the empty trailing () can be left off. Note builtin types: C# string -> String (System.String) [[br]] C# object -> Object (System.Object) [[br]] {{{ public void OnFileChange( object sender, Event e ) }}} to {{{ def onFileChange(sender as Object, e as Event) # no param method public override bool OnInit() }}} -> {{{ def onInit as bool is override # or def onInit as bool is public, override # explicit }}} 13. Calls to methods, properties and attributes/fields. Instance method names, properties and fields are called with a prefix of ''''this.'''' or just ''''.'''' [[br]] and they all must be named starting with a lowercase letter so the calls and settings[[br]] must be modified accordingly. e.g. {{{ gFile.AppendPosn(... -> gFile.appendPosn( ... CreateNewCity() -> .createNewCity # or this.createNewCity }}} Similarly with properties and fields {{{ Street = new Street(this, ... -> .street = Street(this, ... }}} If a method takes no args then any empty trailing () on a method call can/should be left off. 14. Property definition. Depending on the property use, prefix properties with :[[br]] * get - readable property only * set - settable property only * pro - gettable and settable Change property names to start with a lowercase letter 15. Local variables declared and assigned on first use can usually be changed to remove the type definition (type inferred from the assignment) or can still be explicitly typed. {{{ DataItem info = new DataItem() -> info = DataItem() # or info as DataItem = DataItem() }}} 16. Fixup 'For' loops {{{ for ( name = start ; name < stop; ++name ) -> for name as Type in start : stop : 1 # explicit or equally use shortcuts: for name in start : stop : 1 for name in start : stop # if step is one (1) for name in stop # if start is zero (0) and step is one (1) # same as for name in 0 : stop : 1 }}} e.g {{{ for ( int i = 0; i < 200; ++i ) -> for i in 0 : 200 }}} 17. Casting Casts of form '(Type)name' become 'name to Type' [[BR]] e.g. {{{ ... (object) cl.MyString ... --> ... cl.myString to Object ... }}} Casts of form 'a as Type' can also become 'name to Type' or 'name to? Type' e.g {{{ ListEvent le = event as ListEvent; ---> le = event to ListEvent }}} 18. String concatenated with expressions (converted to string) can be modified to use string interpolation. Put the expressions (suitably cobra converted) into the string inside [] e.g. {{{ "Value " + item.Value + " selected item: " + item.Selected ---> "Value [item.value] selected item:[item.selected]" }}} if you have [ and ] symbols, these should be doubled e.g {{{"some constant [ string ]" ---> "some constant [[ string ]]"}}} 19. Boolean expressions must be reviewed to ensure that they will work correctly. Add parentheses to ensure that the C# boolean expressions (which give '''and''' precedence over '''or''') will be evaluated correctly in Cobra (which gives '''and''' and '''or''' equal precedence.) 20. Adding eventHandlers Cobra uses the '''listen''' statement to register event handlers where C# uses an override on the += operator. [[br]] Otherwise normal cobra mapping for method names and reference to methods (vs method calls) apply;[[br]] Methodnames in Cobra must start with a lower case letter and calls to this instance names are prefixed with ''''this.'''' or (easier) ''''.'''' When translating from a 'use'd library namespace, calls to[[br]] Capcased methodnames are referenced in cobra with the first '''char''' lowercased,[[br]] Upcased methodnames are referenced with the first '''word''' lowercased so {{{ EVENT += new Listener(MethodName) in C# becomes listen .EVENT, Listener( ref .methodName ) EVENT += new Listener( EH_METHOD_NAME ) in C# becomes listen .EVENT, Listener( ref .eh_METHOD_NAME ) }}} e.g. {{{ FileChange += new Listener( OnFileChange ) -> listen .fileChange, Listener(ref .onFileChange) }}} 21. Main method 'public void' is default, static is an accessmodifier which becomes ''''shared'''' in cobra, C# attributes (!MetaInformation) are denoted with ''''has'''' e.g. {{{ [STAThread] static public void main() }}} becomes {{{ def main is shared has STAThread }}} 22. Multidimensional and/or fixed size jagged arrays Multidimensional arrays are not supported by the langauge. Jagged arrays of fixed size are possible but difficult to initialise. See http://cobra-language.com/forums/viewtopic.php?f=4&t=654 for more information about these.