I'm trying to create a COM Class Library for my VBA Project and one of the limitations I've seemed to have stumbled across is using constructors on the New() subroutine. After creating the new COM class a Public Sub New() is created with the following comments
' A creatable COM class must have a Public Sub New()
' with no parameters, otherwise, the class will not be
' registered in the COM registry and cannot be created
' via CreateObject.
Obviously though I want to create more subroutines with the new keyword that allow for different parameters. However, when I try to do this and implement the objects in VBA I get an error when trying to input the parameters saying "End of statement expected". If anyone has any information that would greatly be appreciated.
Thank you.
All classes exposed to COM must have a parameterless constructor - period. The reason is that when the client instantiates a class the call eventually goes into CoCreateInstance() global function (or IClassFactory::CreateInstance() which is almost the same). CoCreateInstance() (or IClassFactory::CreateInstance()) have no means for passing parameters into the constructor of the class so that class must have a paremeterless constructor - that constructor will be used to instantiate the class internally.
If you need more than a paremeterless constructor - use a factory class. Pseudocode:
// this should be made COM-exposed
interface IYourClassInterface {
};
// this should not be made COM-exposed
class CYourClass {
public:
CYourClass( parameters ) {}
};
class CYourClassFactory {
public:
CYourClassFactory() {} //<- parameterless constructor
IYouClassInterface* CreateInstance( parameters here )
{
return new CYourClass();
}
};
this way you have a factory class with a paremeterless constructor. You instantiate the factory and then call its creator method for instantiating your class.
Related
I need to prevent class A from being instantiated anywhere but only from another class B, then class B can return the created instance of class A which can be used in any other class.
I understand that B could be a Factory in this example, I looked in the factory pattern in the Haxe code cookbook but it does not seem suit what I am looking for.
In my example class B is doing some work then should return the result in an instance of class A.
no one should be able to create an instance of class A because it is the result of the work that class B performs. anyone needs an instance of A should ask B to do the work and return the resulted A instance
hope I explained it clearly
You would usually do this by using #:allow() metadata in combination with a private constructor:
A.hx:
class A {
#:allow(B)
private function new() {}
}
B.hx:
class B {
public static function create():A {
return new A(); // compiles
}
}
Trying to instantiate A outside of B will result in a compiler error:
class Main {
static function main() {
new A(); // Cannot access private constructor of A
}
}
Note that it's still possible to work around this by using #:access() or #:privateAccess metadata - in Haxe, nothing is ever truly private. It follows a philosophy of "the programmer knows best", which can be very powerful.
Also, you might want to declare A as #:final so nothing can subclass it, because subclasses can access private fields in Haxe. But again, this can be overriden with #:hack metadata.
We are using Groovy and Guice on a project and I came across the following error:
groovy.lang.MissingPropertyException: No such property: myService for class: com.me.api.services.SomeService$$EnhancerByGuice$$536bdaec
Took a bit to figure out, but it was because I was referencing a private class member, that was injected, inside of a closure. Can anyone shed any light as to why this happens?
Furthermore, is there any better way of doing this?
Here is a snippet of what the class looks like:
import javax.inject.Inject
import javax.inject.Singleton
#Singleton
class MyService extends BaseService<Thing> {
#Inject
private ThingDao thingDao
#Inject
private OtherService<Thing> otherService
#Override
List<Thing> findAll() {
List<Thing> things = this.dao.findAll()
things.each {
//Note: This doesn't work!
otherService.doSomething()
}
things
}
I either have to use a standard for loop or not use the injected member which then tends to lead to code duplication.
TLDR;
Either declare otherService public (remove private modifier) or add a getter OtherService<Thing> getOtherService(){otherService}
If you absolutely want to avoid exposing the field through a property, you can do the following trick: create a local variable outside the Closure scope that references your service:
OtherService<Thing> otherService=this.otherService
things.each {
//Note: This will work! Because now there is a local variable in the scope.
//This is handled by normal anonymous inner class mechanisms in the JVM.
otherService.doSomething()
}
Explanation
Under the hood, your closure is an object of an anonymous class, not the object that has your private field, otherService.
This means that it can't resolve a direct reference to the field. Accessing a symbol inside the closure will first look at local variables, and if no match is found, the getProperty() method in Closure will be called to find a property, depending on the resolution strategy that you defined. By default, this is OWNER_FIRST.
If you look the code of Closure#getProperty:
switch(resolveStrategy) {
case DELEGATE_FIRST:
return getPropertyDelegateFirst(property);
case DELEGATE_ONLY:
return InvokerHelper.getProperty(this.delegate, property);
case OWNER_ONLY:
return InvokerHelper.getProperty(this.owner, property);
case TO_SELF:
return super.getProperty(property);
default:
return getPropertyOwnerFirst(property);
}
You see that the owner, delegate and declaring objects need to have matching properties.
In groovy, if you declare a field private, you won't get auto-generated accessor methods, so no properties will be publicly exposed for outside objects.
// What is the technical reason behind this scenarios..?
You're trying to use a statement other than a declaration directly inside the class - rather than within a method. When did you expect the method to get called?
Basically all you can have directly within a type is a bunch of declarations - methods, variables, constructors, events, nested types etc. Method calls (or any other statements) which aren't part of a declaration have to be written within methods, constructors etc.
Method call statement can not be part of a class declaration, but only within Function members declarations scope, such as Methods, Properties, Constructors etc.
For example:
public class ExampleClass
{
private void SayHelloWorld()
{
Console.Writeline("Hello World!");
}
public void CallSayHelloWorldMethod()
{
this.SayHelloWorld();
}
}
At the above example you can see that I call the SayHelloWorld method within the CallSayHelloWorldMethod metod.
Update:
The closest thing I can think of in your case is to use the class's constructor where your method call will be executed as soon as you'll instantiate your class:
public class ExampleClass
{
//The class constructor
public ExampleClass()
{
this.SayHelloWorld();
}
private void SayHelloWorld()
{
Console.Writeline("Hello World!");
}
}
And when you instantiating it, it will be immediately called:
//Your method call will be executed here
ExampleClass exampleClass = new ExampleClass();
You have a few problems... This won't even compile as you are trying to call the method obj.m1() in the class definition.
A obj = new A();
obj.m1(); // Why this code wont work??? --> This must be inside a method
When you create an instance of a class it will create a new member variable called obj which is an instance of A --> A obj = newA() above;
You will now be able to call obj's methods as in your second example.
Also, in order to get this to compile you will need to fix the m2 method:
public void m2() { //--> should have a curly brace
obj.m1(); // But This will work.
}
I've implemented singleton according to this page using System.Lazy<T>.
I wonder, how technically can System.Lazy<T> access constructor of T, when access modificator of constructor is private.
The Lazy<T> is instantiated with an anonymous method as follows:
new Lazy<Singleton>(() => new Singleton());
Anonymous methods are under the covers just private methods located in the class that defines them. Since this is a method in the class, it is allowed to access any other private members of that class including the private constructor.
The code the C# compiler generates closely resembles the following:
Func<Singleton> factory = this.__compiler_generated_method;
new Lazy<Singleton>(factory);
private static Singleton __compiler_generated_method()
{
return new Singleton();
}
I'm working with java me. I tried to switch to a displayable(form2) in Second.java from an okCommand in another displayble(form1) in First.java (see my previous question on that).
I got an error non-static method getForm2() cannot be referenced from a static context. I had to add the word static to form2 declaration and also at the getForm2 method in Second.java before it could work.
Problem now is that a backCommand in form2 can't switch back to form1 in First.java and it pops up the error non-static variable this cannot be referenced from a static context.
I paused and took some time to refresh myself on the language fundamentals on how the static keyword is used and I got to know that a static method is a class method and a non-static method is an instance method and that a non-static cannot call a static method unless an instance of the non-static method is created and also that a static method can't call a non-static method.
I'm really not understanding the implementation as I should, and I'd appreciate some clarification using my example above.
Here's the source below from Second.java the error is coming from form2.setCommandListener(this);
public static Form getForm2() {
if (form2 == null) {
form2 = new Form("form");
form2.addCommand(getBackCommand());
form2.setCommandListener(this);
}
return form2;
You have a static method, but are using this. But this doesn't exist. It would normally reference to an instance of the class, but you don't have one here.
If your method wasn't static and you instantiated an instance of this class then this would work.
e.g.
Second s = new Second();
Form f = s.getForm2(); // if this method wasn't static
Making that method static means little more than namespacing. There isn't an associated instance and no this.
There are couple options. First is to create a static instance of Second and use it in the getForm2:
//...
// static instance
private static Second instance = new Second(/* put constructor arguments here, if any */);
//...
public static Form getForm2() {
if (form2 == null) {
form2 = new Form("form");
form2.addCommand(getBackCommand());
form2.setCommandListener(instance); // --> replace "this" with "instance"
}
//...
From the issues you describe though, I would prefer another option - returning to design you had in previous question and use an instance of Second as an argument passed via constructor of First.
Your First.java would then have lines like:
//...
private final Second second; // instance needed for commandAction
//...
First(Second second) { // constructor with parameter
this.second = second; // save the parameter
//...
}
Then, commandAction method in First.java could use code like:
switchDisplayable(null, second.getSecondForm());
// instead of Second.getSecondForm()