Qt to WP7 - Chapter 4: C# programming

Date: Monday, September 19, 2011, 5:22:40 PM

Tags: Qt

Table of Contents

< Back to Qt to WP7 Guide contents

Microsoft Windows Phone (WP) applications are developed using VB.NET or C# programming languages and corresponding libraries. In the previous chapter we already took a first look at the C# programming language while developing the ShoppingList example application and getting familiar with the WP application development tools.

This chapter maps the essential WP C# language features to the similar C++ language features in Qt. Overview of the C# programming language is provided and the most important WP C# features are described to help you write safe and quality code. Common idioms and programming concepts in WP C# are compared to Qt C++ and, in addition, example code snippets are provided to help you get familiar with WP C# code faster and enhance productivity.

Overview of the C# programming

C# is an elegant and type-safe object-oriented programming language that enables developers to build a variety of secure and robust applications that run on the .NET Framework. C# syntax is highly expressive, yet it is also simple and easy to learn to anyone familiar with C, C++ or Java.

C# syntax simplifies many of the complexities of C++ and provides powerful features such as nullable value types, enumerations, delegates, lambda expressions and direct memory access, which are not found in Java. C# supports generic methods and types, which provide increased type safety and performance, and iterators, which enable implementers of collection classes to define custom iteration behaviors that are simple to use by client code. Language-Integrated Query (LINQ) expressions make the strongly-typed query a first-class language construct

As an object-oriented language, C# supports the concepts of encapsulation, inheritance and polymorphism. All variables and methods, including the Main method, the application's entry point, are encapsulated within class definitions. A class may inherit directly from one parent class, but it may implement any number of interfaces. Methods that override virtual methods in a parent class require the override keyword as a way to avoid accidental redefinition. In C#, a struct is like a lightweight class; it is a stack-allocated type that can implement interfaces but does not support inheritance.

The following chapters give an overview of Windows Phone C# applications in .NET framework and the C# programming guidelines and conventions. See Introduction to the C# language for wider overview of the C# programming language.

Managed Programming in .NET framework

In Symbian Qt, the C++ code is compiled and built directly to executable for Symbian Qt target platform. WP supports managed programming in C# (and VB.NET), as visualized in the following image:

Managed programming visualized

In WP, the C# compiler (and similarly, the VB compiler) compiles the C# (or VB.NET) code to an intermediate language (IL) byte code that conforms to the Common Language Infrastructure (CLI) specification, and to associated metadata. The Common Language Runtime (CLR) executes the byte code. The C# uses metadata to manage type safety, exception handling and array bounds. CLR also manages memory and performs garbage collection.

Overview of a Windows Phone C# application

WP C# applications can consist of one or more .cs files. Each file can contain zero or more namespaces. A namespace can contain types such as classes, structs, interfaces, enumerations and delegates, in addition to other namespaces. The following code snippet outlines a skeleton for a WP C# application containing these basic elements.

// A skeleton of a C# application
using System;
namespace YourNamespace
{
    class YourClass
    {
    }

    struct YourStruct
    {
    }

    interface IYourInterface
    {
    }

    delegate int YourDelegate();

    enum YourEnum
    {
    }

    namespace YourNestedNamespace
    {
        struct YourStruct
        {
        }
    }

    class YourMainClass
    {
        static void Main(string[] args)
        {
            // Your program starts here...
        }
    }
}

The C# Language Specification does not define an explicit coding standard for C# applications. C# coding conventions describes general conventions and best practices for layout and code commenting and provides guidelines for C# language usage. Common naming conventions for C# applications are covered in Guidelines for Names.Secure coding guidelines and design guidelines for class libraries provide a unified programming model that promotes quality, secure code and consistency in C# application design.

Introduction to the C# programming language

In this chapter, the following essential idioms and concepts of WP C# programming language are introduced and compared to the Symbian Qt C++ programming language:

  • Managed Programming
  • Threading
  • Timers
  • Data Binding
  • Memory Management
  • Base Class
  • Class Reference
  • Class Declaration
  • Polymorphism: Base class
  • Polymorphism: Derived class
  • Interfaces: Interface
  • Interfaces: Implementation
  • Properties: Defining a property
  • Properties: Auto-implemented properties
  • Struct
  • Exception Handling
  • Event Handling

The following table addresses the above-mentioned essential programming language idioms and provides a quick comparison between WP C# and Symbian Qt C++ programming languages. See the attached links for more information about the topics. In addition to WP C# and Symbian Qt C++ languages, implementation of some features includes usage of UI description languages XAML and QML respectively.

;

Comparison

Windows Phone C#

Symbian Qt C++

Managed Programming

;

WP C# code is compiled to intermediate language byte code and meta data. Byte code is executed by The Common Language Runtime (CLR) that handles memory management and performs destruction of objects through garbage collection.

Qt C++ code is compiled directly to target platform executable, there is no intermediate language in between. Qt C++ developer is responsible for memory management.

Threading

;

WP C# applications have two threads, the UI thread and the composition thread.

The UI thread is the main thread in Silverlight application taking care of the XAML handling, first-time drawing of visual objects, pre-frame callbacks and executing other user code.

The composition thread handles some work that the UI thread would normally handle. The composition thread combines graphics textures and passes them to the GPU for drawing. Simple storyboard-driven animations are also passed to GPU processing by composition thread.

To avoid blocking the main UI thread, application developers can utilize secondary background threads orBackgroundWorkerclass to perform time-consuming tasks such as downloads and database transactions.

Moving data from background thread to the UI thread can be implemented using shared variables and an event, or by sending a notification to the UI thread usingDispatcher.BeginInvokemethod.BackgroundWorkerclass has own event-based mechanism for background processing.

Read more from: http://msdn.microsoft.com/en-us/library/ff967560(v=vs.92).aspx#BKMK_Threads

Symbian Qt C++ applications have one main thread in which main event loop is running and UI controls can be accessed. UI operations are only allowed from the application main thread.

When asynchronous operations are likely to take a long time and lot of platform resources, usage of Qt's platform-independentQThreadthreads separately may be a good implementation solution.

To create a thread, subclassQThreadand re-implement therun()function.

class MyThread : public QThread
{
Q_OBJECT
protected:
void run();
};
void MyThread::run()
{
...
}

Event handling between Symbian Qt application threads can be implemented using asynchronous notifications through signals and slots mechanism.

Note that similar threading system is also available through QMLWorkerScriptElement.

Timers

;

Timerclass in WP C# provides a simple timer that executes callback methods at specified intervals. Timer runs in a different thread than the application main UI thread and, in order to access objects of the UI thread, it is necessary to inform theDispatcherTimerof the UI thread usingDispatcher.BeginInvoke.

To implement timer directly into the application main UI thread,DispatcherTimerclass can be used.DispatcherTimertimer is integrated into theDispatcherqueue which is processed at a specified interval of time and at a specified priority.

;

Read more aboutTimerfrom: http://msdn.microsoft.com/en-us/library/system.threading.timer(v=vs.95).aspx

;

Read more aboutDispatchedTimerfrom: http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatchertimer(v=vs.95).aspx

QObject, the base class of all Qt objects, provides the basic timer support in Symbian Qt. When your application is running in event loop, you can start a timer withQObject::startTimer().

The main API for timer functionality isQTimer.QTimerclass provides regular timers that emit a signal when the timer fires.

;

QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(doSomething()));
timer->start(1000);

This timer mechanism can also be used in multithreaded applications i.e. in any thread that has an event loop.

Note that similar timer mechanism is also available through QMLTimerelement.

Read more from: http://doc.qt.nokia.com/stable/timers.html

;

Data Binding

;

Data binding in WP C# provides a simple way to display and interact with data, allowing data to flow between the UI and a data object.

When a binding is established and the data changes, the UI elements that are bound to the data can reflect changes automatically. Similarly, changes made by the user in a UI element can be reflected in the data object.

Data binding in WP C# applications can be implemented through XAML or programmatically with C# code.

In XAML, the binding is created usingBindingobject element. Binding can also be expressed as an XAML attribute.

In C# code, binding can be created usingBindingclass:

;

//Create the source string
string s = "Hello";
//Create the binding description
Binding b = new Binding("");
b.Mode = BindingMode.OneTime;
b.Source = s;
//Attach the binding to the target
MyTextBox.SetBinding(TextBlock.TextProperty, b);

;

Read more from: http://msdn.microsoft.com/en-us/library/system.windows.data.binding(v=vs.95).aspx

Property binding is a powerful feature of Symbian Qt that allows values of different elements to be specified in a declarative way and synchronized automatically. It uses signals to notify and update other elements' values when property values are changed.

Property bindings are created in QML using the colon ":" before the value, for example:

;

Rectangle {
    width: parent.width
}

Sometimes it is necessary to bind explicitly to a property of an object that wasn't directly instantiated by QML - generally a property of a class exported to QML by C++.

The QML elementBindingprovides a mechanism to create bindings between properties exposed from C++ and values coming from QML. For example:

;

Binding {
    target: system
    property: "brightness"
    value: slider.value
}

Read more from: http://doc.qt.nokia.com/latest/propertybinding.html

Memory Management

WP C# value types live on the stack, reference type objects live on the heap.

In WP C#, the common language runtime's garbage collector manages the allocation and release of memory for an application. For developers, this means that you do not have to write code to perform memory management tasks when you develop managed applications.

Read more from: http://msdn.microsoft.com/en-us/library/f144e03t%28v=VS.100%29.aspx

;

In addition to garbage collection,IDisposableinterface defines a method to release allocated resources.

Read more from: http://msdn.microsoft.com/en-us/library/system.idisposable.aspx

Symbian Qt C++ objects can live in the stack or in the heap. Classes that support implicit sharing (likeQImage) live always in heap.

Symbian Qt C++ does not have garbage collection. You have to remember to delete objects.

If the parent takes ownership of the Qt C++ object; parent will automatically delete its children in its destructor:

;

QObject* object = new QObject(parent);

;

If the Symbian Qt C++ object has no parent, you have to remember to delete the object:

QObject* object = new QObject();
delete object;

Base Class

All classes in WP C# are derived implicitly fromObject.

;

Read more from: http://msdn.microsoft.com/en-us/library/system.object%28v=VS.100%29.aspx

QObjectis the heart of the Qt C++ Object Model.

;

;

Read more from: http://doc.qt.nokia.com/qobject.html

;

Class Reference

;

refkeyword before parameter type in WP C# method signature means that reference to parameter is copied to the method. This reference still refers to the same object on the heap as the original reference used in the caller's argument.

;

Address addr = new Address();
addAddress( ref addr);

void addAddress(ref Address addr)
{
    Console.WriteLine("Name: {0}, Address: {1} added.",
                     addr.name, addr.address);
}

outkeyword before parameter type in WP C# method signature means that parameters are only passed back to the calling function. You must assign a value to anoutparameter before your method returns.

;

Address addr = new Address();
modifyAddress( out addr);

void modifyAddress(out Address addr)
{
    addr = new Address();
    addr.name = "Joe";
    addr.address = "C# Station";
}

Note that there is no pointers (*) in WP C#. Pointers are allowed in unsafe mode only.

Read more from: http://msdn.microsoft.com/en-us/library/8f1hz171%28v=VS.100%29.aspx

Qt C++ has implicit sharing. Implicitly shared classes are both safe and efficient when passed as arguments, because only a pointer to the data is passed around, and the data is copied only if and when a function writes to it, i.e. copy-on-write.

;

Read more from: http://doc.qt.nokia.com/implicit-sharing.html

;

Classes that do not support implicit sharing, like your own classes, should be used in references like regular C++ classes. For example:

;

Address* addr = new Address(this);
addAddress(*addr);

void addAddress(MyAddress& address)
{
}

Class Declaration

;

Declaring a class in WP C#.

;

MyObject myObject = new MyObject();

;

Objects are derived automatically fromObjectbase class and automatically have default empty constructor and destructor.

;

Note that C# does not use header files; all code is written into .cs files.

;

// Namespace Declaration
using System;
class MyObject
{
}

Declaring a class in Qt C++.

;

MyQObject* myObject = new MyQObject (this);

#include 
class MyQObject : public QObject
{
    Q_OBJECT
    public:
        MyQObject (QObject *parent = 0);
        ~ MyQObject ();
}

MyQObject:: MyQObject (QObject *parent):QObject(parent)
{
}

MyQObject::~ MyQObject ()
{
}

Polymorphism: Base class

Example of WP C# base class implementation.

;

;

public class DrawingObject
{
    // virtual modifier indicates to 
    // derived classes that they can
    // override this method
    public virtual void Draw()
    {
    }
}

Example of Qt C++ base class implementation.

;

class DrawingObject : public QObject
{
public:
DrawingObject(QObject* parent = 0);
// virtual modifier indicates to
// derived classes that they can
// override this method
virtual void Draw();
};

Polymorphism:

Derived class

Example of deriving base class in WP C#.

;

public class Line : DrawingObject
{
// override modifier allows a method
// to override the virtual method
// of its base class at run-time
public override void Draw()
{
}
}

Note that multiple inheritance is not supported in C#, although a class can implement any number of interfaces.

Example of deriving base class in Qt C++.

;

class Line : public DrawingObject
{
public:
Line(QObject* parent = 0);
// Overrides the virtual base class
// method
void Draw();
};

Interfaces: Interface

;

Example of WP C# interface.

;

interface ISomeInterface
{
    void SomeMethodToImpl();
}

Example of Qt C++ interface.

;

class ISomeInterface
{
    virtual void SomeMethodToImpl();
};

Interfaces: Implementation

MyInterfaceImplimplementsISomeInterfaceinterface in WP C#.

;

class MyInterfaceImpl
    : ISomeInterface
    {
        public void SomeMethodToImpl()
        {
        }
}

MyInterfaceImplimplementsISomeInterfaceinterface in Qt C++.

;

class MyInterfaceImpl
: public QObject, ISomeInterface
{
    public:
    MyInterfaceImpl(QObject* parent=0);

    void SomeMethodToImpl();
};

Properties: Defining a property

;

Defining WP C# property.

;

public class MyObject
{
    private int m_id = 0;

    // ID property
    public int ID
    {
        get
        {
            return m_id;
        }

        set
        {
            m_id = value;
        }
    }
}

Calling ID property.

MyObject myObject = new MyObject();
myObject.ID = 100;
int i = myObject.ID;

Read more from: http://msdn.microsoft.com/en-us/library/x9fsa0sw.aspx

Defining Qt C++ property.

;

class MyObject : public QObject
{
    Q_OBJECT

    // ID property
    Q_PROPERTY(int id READ ID WRITE setID)

    public:
    MyObject(QObject* parent=0);

    int ID() const;
    void setID(const int);

    private:
    int m_id;
};

;

Calling ID property.

MyObject* myObject = new MyObject();
myObject->setID(100);
int i = myObject->ID();

Properties: Auto-implemented properties

;

WP C# has Auto-implemented properties that can be declared in a single line. C# compiler creates the backing store field behind the scenes to contain the property value, giving the same logic that exists with traditional properties, but saving you from having to use all of the syntax of the traditional property.

public class MyObject
{
    public int ID { get; set; }
}

Calling ID property.

MyObject myObject = new MyObject();
myObject.ID = 100;
int i = myObject.ID;

Read more from: http://msdn.microsoft.com/en-us/library/bb384054.aspx

Qt C++ doesn't have Auto-implemented properties.

Struct

In WP C#, a struct is a value type while a class is a reference type. Value types hold their value in memory where they are declared, reference types hold a reference to an object in memory.

;

struct MyStruct
{
    // Property in the struct
    public int Width { get; set; }

    public void SayWidth()
    {
    }
}

Read more from: http://msdn.microsoft.com/en-us/library/saxz13w4.aspx

Example of Qt C++ struct. Qt C++ structs can have methods but cannot have properties.

;

struct MyStruct
{
// Can't define property into
// struct
//Q_PROPERTY(int width READ width WRITE setWidth)

private:
int m_width;

public:
void sayWidth();
int width() const;
void setWidth(const int);
};

void MyStruct::sayWidth()
{
qDebug() << m_width;
}

int MyStruct::width() const
{
return m_width;
}

void MyStruct::setWidth(const int w)
{
m_width = w;
}

Exception Handling

In WP C#, you can handle exceptions intry/catch/finallyblocks, for example:

;

FileStream inStream = null;

try
{
    inStream = File.OpenRead("somefile.txt");
}
catch(Exception ex)
{
    Console.WriteLine(ex.ToString());
}
finally
{
    if (inStream != null)
    inStream.Close();
}

Read more from: http://msdn.microsoft.com/en-us/library/ms229005.aspx

Qt C++ has some exception handling functionality but it is not fully compatible between all supported platforms. The Symbian platform implements its own exception system that differs from the standard C++ mechanism.

Event Handling

The event model in the WP C# is based on having an event delegate that connects an event with its handler. To raise an event, two elements are needed: delegate and event data.

EventHandleris a predefined delegate andEventArgsis event's data.

;

For example, to associate the button clicked event with the method that will handle the event (OnClick), add an instance of the (EventHandler) delegate to the (Click) event.

;

// Create Button
Button btn = new Button();
// Create event handler for Button
// Click event
btn.Click+=new EventHandler(OnClick);

public void OnClick(object sender,EventArgs e){
    // Button clicked
}

Read more from http://msdn.microsoft.com/en-us/library/system.eventhandler.aspx

;

Qt uses signal and slot mechanism. Signals and slots are used for communication between objects in Qt C++.

Another mechanism to receive and handle events is to subclassQObjectand to re-implement the necessary event handling functions.

;

Note that Qt signal and slot event handling mechanism is also accessible through QML code.

;

// Create Button
QPushButton* btn = new QPushButton(this);
// Listen/connect Button clicked()
// signal to btnClicked() slot
connect(btn, SIGNAL(clicked()), this, SLOT(btnClicked()));

void MyClass::btnClicked(){
// Slot where Button clicked signal is
// sent
}

Comparison between C# and Qt C++ programming language fundamentals

See C# Language Specification for more details about all aspects of the C# programming language. See C# Programming Guide for more information about C# programming.

Differences between C# and Qt C++

The following table summarizes the most essential differences between syntax and features of C# and Qt C++ programming languages.

Differences between C# and Qt C++ programming languages

;

Inheritance: C# classes can implement any number of interfaces, but can inherit from only one base class. Furthermore, C# structs do not support inheritance, and do not support explicit default constructors (one is provided by default). In Qt C++, structs can have methods but cannot have properties.

Arrays: In Qt C++, arrays are provided as container classes. STL containers can also be used. Qt C++ containers handle array objects as pointers (excluding copy-on-write). In C#, arrays are objects that include methods and properties. The syntax for declaring C# arrays is different from that for C++ arrays: the tokens "[]" appear following the array type in C#, not the variable.

Booleans: In Qt C++, thebooltype is essentially an integer. In QML, a boolean is a binary true/false value. In C#, there is no conversion between thebooltype and other types.

Passing parameters: In Qt C++, classes are passed as pointers through implicit sharing. Class data is copied only if and when a function writes to it. In C#, classes are passed by reference and structs are passed by value unless explicitly passed by reference with the ref or out parameter modifiers.

Theswitchstatement: Unlike the Qt C++switchstatement, C# does not support fall-through from one case label to another.

Delegates: C# delegates are roughly similar to method pointers in Qt C++. However, delegates are type-safe and secure.

Base-class methods: C# supports thebasekeyword for calling the overridden base class members from derived classes. Also, overriding virtual or abstract methods is explicit in C#, using the override keyword.

Method hiding: Qt C++ supports the implicit "hiding" of method through inheritance. In C#, you must use the new modifier to explicitly hide inherited members.

Preprocessor directives are used for conditional compilation. No header files are used in C#.

Exception handling: C# provides thefinallykeyword to provide for code that should be executed regardless of whether an exception is thrown. In Qt C++, exception handling is not fully compatible between all supported platforms and error codes are used instead of throwing exceptions. Furthermore, Symbian platform has its ownTRAP/Leave/CleanupStackbased exception handling mechanism.

C# operators: C# supports additional operators such asisandtypeof. It also introduces different functionality for some logical operators.

Thetypedefkeyword: In Qt C++,typedefis used to create shorter or more convenient names for types that have already been declared. In C#, theusingdirective provides this capability.

Theexternkeyword: In Qt C++,externis used to import types and functions. In C#,externis used to create aliases for using different versions of the same assembly.

Thestatickeyword: In Qt C++,staticcan be used both to declare class-level entities and to declare types that are specific to a module. In C#,staticis only used to declare class-level entities.

TheMainmethod in C# is declared differently from the main function in Qt C++. In C# it is capitalized and always static. Also, support for processing of command-line arguments is much more robust in C#.

Pointers are allowed in C#, but only in unsafe mode.

Overloading operators is performed differently in C#.

Strings: In Qt C++ a string is simply an array of characters. In C#, strings are objects that support robust searching methods.

Theforeachkeyword enables you to iterate through arrays and collections in C#.

Globals: In C#, global methods and variables are not supported. Methods and variables must be contained within a class or struct.

The#definepreprocessing directive: In Qt C++ the#definedirective is commonly used to declare constant values. In C# the#definedirective cannot be used for this purpose. Constants in C# are best defined as enumerated types (integral values only) or as static members of a class or struct. If you have several such constants, consider creating a separate "Constants" class to hold them.

Importing types: In Qt C++, types common to multiple modules are placed in header files. In C#, this information is available via metadata.

Local variables in C# cannot be used before they are initialized.

Memory management: Qt C++ is not a garbage collected language; memory that is not explicitly release remains allocated until the process terminates. C# is a garbage collected language.

Destructors: C# has different syntax for deterministically releasing unmanaged resources.

Constructors: Similar to Qt C++, if you do not provide a class constructor in C#, a default constructor is automatically generated for you. The default constructor initializes all the fields to their default values.

C# does not support bit fields.

C# input/output services and formatting rely on the run-time library of the .NET Framework.

In C#, method parameters cannot have default values. Use method overloads if you want to achieve the same effect.

In C#, generic types and methods provide for type parameterization in a way that is similar to C++ templates in Qt. There are significant differences, however. For example, in C# generic type information is preserved at run time.

Theaskeyword is similar to a standard cast, except that rather than throw an exception if the conversion fails, the return value isnull. This is similar to usingstatic_castin Qt C++, which, unlikedynamic_castin standard C++, performs no run-time check and hence does not throw an exception on failure. Qt C++qobject_castfunction behaves similarly to the standard C++dynamic_cast, with the exception that it doesn't require RTTI support and it works across dynamic library boundaries.

C# for C++Developersprovides more information about how to adapt to C# development as a C++ developer.

Summary

In this chapter, we looked at C# programming from the perspective of a Symbian Qt C++ developer. C# is a strongly typed, object-oriented programming language that uses static binding. The most essential differences between Qt C++ and C# were described and visualized using comparisons and code snippets. However, several C# concepts are similar to the Qt C++ concepts so the knowledge of Qt C++ and the object oriented programming in general will help you to master C# quickly.

Related Resources

To go deeper into C# programming language, visit:

< Back to Qt to WP7 Guide contents

 
blog comments powered by Disqus