Instantiating C# Class Members in C++ using COM - c#

I would like to create a C# class object in C++ and set its member fields.
Although I am able to create a C++ class object, I am unable to access it's members and set member field values.
/// <summary>
/// Class for AQS Entity
/// </summary>
[ClassInterface(ClassInterfaceType.None)]
[Guid("70F12A44-B91D-474D-BD70-32B1ACE041D6")]
[ProgId("AQSEntity")]
public class AQSEntity : IEntity
{
public AQSEntity()
{
sRecoveryDBName = String.Empty;
arrSourceMailboxesEntity = null;
sQueryString = String.Empty;
}
[MarshalAs(UnmanagedType.BStr)]
public string sRecoveryDBName = string.Empty;
[MarshalAs(UnmanagedType.ByValArray)]
public MailBoxCollection arrSourceMailboxesEntity;
[MarshalAs(UnmanagedType.BStr)]
public string sQueryString;
}
and the IEntity class is defined below
[Guid("5C71057E-9FD9-47D5-B022-8D5F9C7007D3")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IEntity
{
}
In C++,
IEntity* pTest1 = NULL;
hr = CoCreateInstance(__uuidof(**AQSEntity**),NULL,CLSCTX_INPROC_SERVER,__uuidof(IEntity),(void**)&pTest1);
I want to access members of AQSEntity class in C++. But I am unable to access them.
pTest1-> sQueryString
gives error.
'sQueryString' : is not a member of
'AsigraExchange::IEntity' C:\PROJECTS\COM\COMClient\COMClient.cpp 168
Can anyone please suggest where I am wrong.
Thanks,
Gagan

Everything behaves exactly as it should :)
In your C++ project, you are allowed to access all the methods declared on your IEntity interface, which there are none.
Your implementation, i.e. AQSEntity class, should implement all the IEntity members. The methods which are now declared in that class are member of the class, they are not related to IEntity in any way.
This means you need to declare all the required methods inside IEntity interface and then implement them in AQSEntity. Notice that you are also exposing the fields of the class, not the methods. You will have to define methods (or properties, which will get converted to methods on C++ side) and then implement them. Something like:
public interface IEntity
{
public string RecoveryDBName { get; }
}
You also have to specify [MarshalAs] attributes in the interface, although UnmanagedType.BStr is default for strings, so you can omit them.
EDIT:
based on comments, it seems that IEntity is just a marker interface, not intended to be exposed as an API (attributes might be better option here, as IEntity won't be used on client side anyway).
In this case there are two options:
1) better approach, although it requires more work: derive IAQSEntity interface from IEntity, declare methods on it, and implement that on AQSEntity class
2) less work, but more brittle: Mark AQSEntity as ClassInterfaceType.AutoDual instead of ClassInterfaceType.None - this will expose the members to COM clients, but will be much harder to version and it will also expose the base type members.
Here's what I would choose:
[ClassInterface(ClassInterfaceType.None)]
...
[Entity] // instead of IEntity marker interface
public class AQSEntity : IAQSEntity
{
public string RecoveryDbName { get; }
}
[Guid("...")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IAQSEntity // no base interface IEntity!
{
string RecoveryDbName { get; }
}
The only drawback of using Entity attribute instead of IEntity marker interface is if you want to use the interface as constraint for generics

Your interface does indeed not contain any members. You need to put the members into the interface and then implement that interface in your class.

Related

How I can force an implemented Class to use an Entity which has a specific Parameter?

I have an Interface as below:
public interface IRepository<T> where T : class
{
T is type of my entities.
In this interface I have some methods which will use Entity's Id property. So, How can I guarantee that, the Entity has Id property when some body wants to implement this interface?
Interfaces to the rescue!
Define an interface as follows:
// Why IEquatable<T>? Because you don't want identifiers that may not
// be able to prove that they're equal or not. Most commonly used
// types used as identifiers already implement IEquatable<T>. For example:
// int, Guid...
public interface ICanBeIdentifiable<TId> where TId : IEquatable<TId>
{
TId Id { get; }
}
...and change your repository interface signature as follows too:
public interface IRepository<T> where T : class, ICanBeIdentifiable<Guid>
...
...or if you want to absolutely open the door to any identifier type:
public interface IRepository<TId, T>
where TId : IEquatable<TId>
where T : class, ICanBeIdentifiable<TId>
The main drawback is your domain objects must implement the whole new interface, but it's worth the effort.
You can add additional interface which will push every Entity to have Id property
public interface IEntity
{
int Id { get; set; }
}
public interface IRepository<T> where T : class, IEntity
{
}

Why constants are not allowed in c# interface? [duplicate]

For example, suppose I want an ICar interface and that all implementations will contain the field Year. Does this mean that every implementation has to separately declare Year? Wouldn't it be nicer to simply define this in the interface?
Though many of the other answers are correct at the semantic level, I find it interesting to also approach these sorts of questions from the implementation details level.
An interface can be thought of as a collection of slots, which contain methods. When a class implements an interface, the class is required to tell the runtime how to fill in all the required slots. When you say
interface IFoo { void M(); }
class Foo : IFoo { public void M() { ... } }
the class says "when you create an instance of me, stuff a reference to Foo.M in the slot for IFoo.M.
Then when you do a call:
IFoo ifoo = new Foo();
ifoo.M();
the compiler generates code that says "ask the object what method is in the slot for IFoo.M, and call that method.
If an interface is a collection of slots that contain methods, then some of those slots can also contain the get and set methods of a property, the get and set methods of an indexer, and the add and remove methods of an event. But a field is not a method. There's no "slot" associated with a field that you can then "fill in" with a reference to the field location. And therefore, interfaces can define methods, properties, indexers and events, but not fields.
Interfaces in C# are intended to define the contract that a class will adhere to - not a particular implementation.
In that spirit, C# interfaces do allow properties to be defined - which the caller must supply an implementation for:
interface ICar
{
int Year { get; set; }
}
Implementing classes can use auto-properties to simplify implementation, if there's no special logic associated with the property:
class Automobile : ICar
{
public int Year { get; set; } // automatically implemented
}
Declare it as a property:
interface ICar {
int Year { get; set; }
}
Eric Lippert nailed it, I'll use a different way to say what he said. All of the members of an interface are virtual and they all need to be overridden by a class that inherits the interface. You don't explicitly write the virtual keyword in the interface declaration, nor use the override keyword in the class, they are implied.
The virtual keyword is implemented in .NET with methods and a so-called v-table, an array of method pointers. The override keyword fills the v-table slot with a different method pointer, overwriting the one produced by the base class. Properties, events and indexers are implemented as methods under the hood. But fields are not. Interfaces can therefore not contain fields.
Why not just have a Year property, which is perfectly fine?
Interfaces don't contain fields because fields represent a specific implementation of data representation, and exposing them would break encapsulation. Thus having an interface with a field would effectively be coding to an implementation instead of an interface, which is a curious paradox for an interface to have!
For instance, part of your Year specification might require that it be invalid for ICar implementers to allow assignment to a Year which is later than the current year + 1 or before 1900. There's no way to say that if you had exposed Year fields -- far better to use properties instead to do the work here.
The short answer is yes, every implementing type will have to create its own backing variable. This is because an interface is analogous to a contract. All it can do is specify particular publicly accessible pieces of code that an implementing type must make available; it cannot contain any code itself.
Consider this scenario using what you suggest:
public interface InterfaceOne
{
int myBackingVariable;
int MyProperty { get { return myBackingVariable; } }
}
public interface InterfaceTwo
{
int myBackingVariable;
int MyProperty { get { return myBackingVariable; } }
}
public class MyClass : InterfaceOne, InterfaceTwo { }
We have a couple of problems here:
Because all members of an interface are--by definition--public, our backing variable is now exposed to anyone using the interface
Which myBackingVariable will MyClass use?
The most common approach taken is to declare the interface and a barebones abstract class that implements it. This allows you the flexibility of either inheriting from the abstract class and getting the implementation for free, or explicitly implementing the interface and being allowed to inherit from another class. It works something like this:
public interface IMyInterface
{
int MyProperty { get; set; }
}
public abstract class MyInterfaceBase : IMyInterface
{
int myProperty;
public int MyProperty
{
get { return myProperty; }
set { myProperty = value; }
}
}
Others have given the 'Why', so I'll just add that your interface can define a Control; if you wrap it in a property:
public interface IView {
Control Year { get; }
}
public Form : IView {
public Control Year { get { return uxYear; } } //numeric text box or whatever
}
A lot has been said already, but to make it simple, here's my take.
Interfaces are intended to have method contracts to be implemented by the consumers or classes and not to have fields to store values.
You may argue that then why properties are allowed? So the simple answer is - properties are internally defined as methods only.
Interfaces do not contain any implementation.
Define an interface with a property.
Further you can implement that interface in any class and use this class going forward.
If required you can have this property defined as virtual in the class so that you can modify its behaviour.
Beginning with C# 8.0, an interface may define a default implementation for members, including properties. Defining a default implementation for a property in an interface is rare because interfaces may not define instance data fields.
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/interface-properties
interface IEmployee
{
string Name
{
get;
set;
}
int Counter
{
get;
}
}
public class Employee : IEmployee
{
public static int numberOfEmployees;
private string _name;
public string Name // read-write instance property
{
get => _name;
set => _name = value;
}
private int _counter;
public int Counter // read-only instance property
{
get => _counter;
}
// constructor
public Employee() => _counter = ++numberOfEmployees;
}
For this you can have a Car base class that implement the year field, and all other implementations can inheritance from it.
An interface defines public instance properties and methods. Fields are typically private, or at the most protected, internal or protected internal (the term "field" is typically not used for anything public).
As stated by other replies you can define a base class and define a protected property which will be accessible by all inheritors.
One oddity is that an interface can in fact be defined as internal but it limits the usefulness of the interface, and it is typically used to define internal functionality that is not used by other external code.

extend a class to conform to an interface?

I have an interface:
interface IFoo {
int foo(int bar);
}
Can I now extend an existing class to conform to the interface? Say class String. I know I can define the foo() method on strings. But is it possible to go further and tell the compiler that strings can be cast to IFoo?
You can do it with other classes, but not with System.String, because it is sealed.
If you wanted to do this to a non-sealed class, you could simply derive from it, add appropriate constructors, and put the interface as something that your new class implements.
interface IFoo {
int Size {get;}
}
// This class already does what you need, but does not implement
// your interface of interest
class OldClass {
int Size {get;private set;}
public OldClass(int size) { Size = size; }
}
// Derive from the existing class, and implement the interface
class NewClass : OldClass, IFoo {
public NewCLass(int size) : base(size) {}
}
When the class is sealed, your only solution of presenting it as some interface through composition: write a wrapper class implementing your interface, give it an instance of the sealed class, and write method implementations that "forward" calls to the wrapped instance of the target class.
I think the question could be restated as, 'can I use extension methods to make a sealed class implement an interface that it did not before?' As others point out, the String class is sealed. However, I think you have to name what interfaces a class implements in its declaration:
public someClass : IFoo
{
// code goes here
}
So you can't do this directly to String, not just because it is sealed, but because you do not have the source code for it.
The best you can do is make your own class that has-a String and use it like a string. Anything that a String does that you need to do you will either have to do on its String member (thus making it public), or you will have to wrap/reimplement the method you need:
public class betterString : IFoo
{
public String str {get; set;}
public foo(int i)
{
// implement foo
}
}
then later, when using it:
public void someMethod(betterString better)
{
better.foo(77);
System.Console.WriteLine(better.str);
}

Allow only internal implementations for public interface

This question is similar to Can I make a type "sealed except for internal types" but with interfaces instead of classes.
I want to make a library with something like:
public class SomeClass {
ISupporter Supporter {get; set;}
}
public interface ISupporter {/*Some public methods*/}
internal interface ISupporterInternal {/*Some secret methods*/}
public class SupporterA : ISupporterInternal {/*Includes some explicit interface impls of ISupporterInternal*/}
public class SupporterB : ISupporterInternal {/*Includes some explicit interface impls of ISupporterInternal*/}
The user of the library should be able to set a supporter object for instances of SomeClass. The user should also be able to use the methods from ISupporter but I don't want the user to create his own implementations of ISupporter and have him assign instances of those implementations.
Is there any way besides throwing an exception when the type of the assigned supporter is not derived from ISupporterInternal.

Type safety through inheritance (2)

This is an extension to my previous question: Type safety through inheritance
I created a new question instead of updating my old as this one dives deeper into this topic.
My original purpose was to declare a method that returns an object of the implementing classes type. One such method might look like GetSimpleClone() in the following:
I have a base interface IEntity that declares the method GetSimpleClone() and is implemented by several other interfaces, for example IPerson.
public interface IEntity<T> : where T : IEntity<T>
{
T GetSimpleClone();
}
public interface IPerson : IEntity<IPerson>
{
}
The interface IAddress also implements IEntity. However another interface IVenue inherits from IAddress. As I described in the beginning, I want the GetSimpleClone() method in IAddress to return an object of type IAddress while the same method in IVenue should return an object of type IVenue. Therefore the declaration of IAddress differs from IPerson as it has to declare a generic type itself:
public interface IAddress<T> : IEntity<T> where T : IAddress<T>
{
}
public interface IVenue : IAddress<IVenue>
{
}
Now the problem is that IPersonhas a reference to IAddress and understandably the compiler forces me to define the generic type of IAddress.
public interface IPerson : IEntity<IPerson>
{
IAddress<"Compiler: Define Type!!"> Address { get; set; }
}
I really can't see a solution to this problem and would appreciate any help from you, even if it is just to say that there is simply no solution. :)
Thanks in advance...
To accomplish that, you will need to introduce yet another generic:
public interface IPerson<T> : IEntity<IPerson<T>>
where T : IAddress<T>
{
IAddress<T> Address { get; set; }
}
The better solution I could think of is just to put aside the safety thing and create a good base IAddress interface with a common methods, like getAddressString, and use it for all types of addresses you may want to have.

Categories

Resources