Different access modifiers for property getter/setter in C++/CLI - c++-cli

Is it possible to specify different access modifiers for property getter and setter using C++/CLI syntax? In C# one would write:
class Foo
{
public string Bar
{
get;
internal set;
}
}

This should do:
public:
property String^ Bar
{
String^ get();
private:
void set(String^);
}
(Edited following Hans Passant's comment).

Related

__property to property

I am converting a project from /oldsyntax to /clr and have problems to convert my properties in the public __gc class Reader which has now become public ref class Reader
I have these properties (amongst others) in the .h file
__property void set_Xml(System::String *value);
__property System::String *get_Xml();
and then in the .cpp file I have
void Reader::set_Xml(System::String *value)
{
if(value->Chars[0] == '<'){
reader->put_xml(stlString(value).c_str());
}
else {
reader->put_xml_file(stlString(value).c_str());
}
}
System::String *Reader::get_Xml()
{
return gcString(reader->get_xml(), reader->state.is_utf8);
}
How do I rewrite this so that it can compile with /clr. I am using Visual Studio 2010 ?
The link posted in the comments has all the information on the new syntax for properties.
Old: Declare methods with a specific naming convention, decorate them with __property.
New: Declare a property block within your class, and have methods with an additional level of scope. (Note: I'm not sure if "additional level of scope" is the proper way to describe it, see below.)
For a property named Xml of type String, the syntax would be:
In the header file:
public ref class Reader
{
public:
property String^ Xml
{
String^ get();
void set(String^ value);
}
}
In the .cpp file:
String^ Reader::Xml::get()
{
return whatever;
}
void Reader::Xml::set(String^ value)
{
whatever = value;
}

Point to the function created in C# project from generic typename in C++/CLI

C++/CLI :
public interface class ITest{
public:
virtual void doSomething (){
}
}
public ref Base {
...........
...........
}
generic <typename T> where T : ITest
public ref Derived : Base{
public:
virtual void doNothing (){
}
}
public ref AnotherClass {
public:
generic<class T> where T : Base
static int justDoThis(){
//Problem!!
}
}
C# :
In C# there are two classes A and B. A inherits from the ITest and B inherits from Derived where A is used as the typename. Also, B has a private variable of type A. So, from main function AnotherClass.justDoThis<B>() is called where B is passed as the generic type.
"//Problem!!" Part :
Now I have to create a new instance of B in this section and also access the A which is private variable in B.
So if I take your paragraph of description of the C# code:
class A : ITest {}
class B : Derived<A>
{
private A someVariableOfTypeA;
}
class Program
{
void Main(string[] args)
{
AnotherClass.justDoThis<B>();
}
}
And the problem is that you want to do this:
public ref AnotherClass {
public:
generic<class T> where T : Base
static int justDoThis()
{
// Problem!!
Something^ actuallyB = gcnew Something();
A^ a = actuallyB->someVariableOfTypeA;
}
}
Issue #1: You can allow creation of new objects of the generic type by specifying gcnew as another generic constraint. (In C#, this would be new.) This will require that the generic type have a default (i.e., parameterless) constructor, which you can access with the normal gcnew.
generic<class T> where T : Base, gcnew
static int justDoThis()
{
T^ t = gcnew T();
}
Issue #2: You cannot access private variables within an object. That's what private means. If you want to give justDoThis access to the A object, then add an appropriate public method or property to Base. The method or property would return type ITest. You could also put that method/property on a new interface (perhaps named IHaveAnITestAccessorMethod), and add that as another generic constraint, and B satisfies all the constraints.
Note that it won't do any good to make the variable public on type B: justDoThis doesn't know about B, it only knows about T, which is a Base with a no parameter constructor.
Disclaimers:
I didn't check my syntax with a compiler.
Yes, you can do anything with reflection, but that's a bad design. Don't do that, fix your code the right way.

Can't reference C++/cx class from xaml? (UWP)

I have a C++ class in my application testclient:
namespace testclient{
namespace models{
ref class myclass sealed{
public:
myclass();
property String^ getstring
{
String^ get()
{
return string;
}
}
private:
String^ string = "test";
}}}
I want to bind a control to the property getstring, and from what little I understand of UWP XAML data binding, I have to include this in the top of the MainPage.xaml: xmlns:data="using:testclient.models Problem is, intellisense is telling me "Undefined namespace. The 'using' URI refers to a namespace called testclient.models that could not be found." What am I doing wrong?
EDIT: I've found the problem goes away when I put the class in Mainpage.Xaml.h, but I'd rather not do this...
Every binding consists of a binding target and a binding source. Typically, the target is a property of a control or other UI element, and the source is a property of a class instance.
If you want to use myclass as datasource to MainPage's UI elements, you need to make sure the instance of the myclass is accessible to MainPage. That's why your first version resulted in error. In order to modify mainPage.Xaml.h as little as possible, you could follow steps below by creating a separate file(I simplified the member of myclass for easy debugging):
1) Create myclass.h:
namespace TestClient{
namespace models{
public ref class myclass sealed
{
private:
int test = 1;
public:
myclass()
{
}
property int gettest
{
int get() { return test; };
}
};
}
}
2) in MainPage.h, add following:
#include "myclass.h"
namespace TestClient
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public ref class MainPage sealed
{
private:
TestClient::models::myclass myTest;
.......
}
.........
}
3) Then you can manipulate myclass data in mainPage.cpp as you want. Codes may be like below:
MainPage::MainPage()
{
InitializeComponent();
int i = this->myTest.gettest;
...........
}
Still I have a question: while so many namespace nested? Also you can find a sample about data binding here just for your reference.

How to access a non-public variable in a base class?

I'm in a method of a derived class, loosely as follows:
Class Base
{
private:
int variableIWantToAccess;
}
Class Derived : public Base
{
public someMethod() {
variableIWantToAccess++; <<-----ERROR
}
How do I access the variable that's declared in the base class? I'm unable to access it because it is private.
You should declare it as protected instead of private.
Protected members of a class are accessible for the class descendants only.
Leave the field private and create a pair of protected getter / setter methods instead (for the same reasons you wouldn't expose a public field).
Class Base
{
private:
int variableIWantToAccess;
protected:
int GetVariable() { return variableIWantToAccess; }
void SetVariable(int var) { variableIWantToAccess = var; }
}

Implementing an interface declared in C# from C++/CLI

Say I have a C# interface called IMyInterface defined as follows:
// C# code
public interface IMyInterface
{
void Foo(string value);
string MyProperty { get; }
}
Assume I also have a C++/CLI class, MyConcreteClass, that implements this interface and whose header is declared as follows:
// C++/CLI header file
ref class MyConcreteClass : IMyInterface
{
public:
};
How does one implement the method Foo and the property MyProperty in the C++/CLI header?
My attempt results in the following compile error:
error C3766: 'MyConcreteClass' must
provide an implementation for the
interface method 'void
IMyInterface::Foo(System::String^
value)'
public ref class MyConcreteClass : public IMyInterface
{
public:
virtual void __clrcall Foo(String^ value) sealed;
virtual property String^ __clrcall MyProperty
{ String^ get() sealed { String::Empty; } }
};
Interfaces need to be defined as virtual. Also note the "public IMy.." after the class decleration, it's a slighly different syntax than C#.
If you can, seal the interface members to improve performance, the compiler will be able to bind these methods more tightly than a typical virtual members.
Hope that helps ;)
I did not compile it but looks good to me... Oh and also, defining your methods as __clrcall eliminates dangers of double thunk performance penalties.
edit
the correct syntax for a property is:
public ref class MyConcreteClass : public IMyInterface
{
public:
virtual property String^ MyProperty
{
String^ get() sealed { return String::Empty; };
void set( String^ s ) sealed { };
}
};
or, when putting the definition in the source file:
public ref class MyConcreteClass : public IMyInterface
{
public:
virtual property String^ MyProperty
{
String^ get() sealed;
void set( String^ s ) sealed;
}
};
String^ MyConcreteClass::MyProperty::get()
{
return String::Empty;
}
void MyConcreteClass::MyProperty::set( String^ )
{
//...
}