Property accessibility in Kotlin - kotlin

Here is what we know from the docs: getter of public property can't be private (seems logical enough), so:
#Inject
var repository: MyExampleRepository? = null
private get
won't compile.
Ok, so maybe we can make property private and define setter public?
#Inject
private var repository: MyExampleRepository? = null
public set
This will compile and value will actually be injected, but I still can't use this in code, so:
service.repository = null
gives compilation error:
Kotlin: Cannot access 'repository': it is 'private' in 'MyService'
I wonder if it is possible to have private property with public setter.

It's a known issue: KT-10385:
Kotlin doesn't generate setter method for the following code:
private val someProperty: Integer
public set
The intention is to generate a set only property. Use case including
spring dependency injection.

Related

Kotlin protected property can not be accessed in other module

Just when I thought I understood it, I got the following issue.
I have a base class in another module (called base here)
It looks like that:
open class BaseTest {
companion object {
lateinit var baseTest: BaseTest
}
protected open var someProperty: String? = "base"
}
I want to set that property and made it protected so my extended class in another module could access it.
class Extended: BaseTest() {
fun extendedCall() {
BaseTest().someProperty = "extended"
baseTest.someProperty = "extended"
}
}
However, neither the static one, not the direct property is accessable stating the following error:
Cannot access 'someProperty': it is protected in 'BaseTest'
But shouldn't that be accessable since Extended inherents from BaseTest()? I mean the definition of protected is "Declarations are only visible in its class and in its subclassess" so what have I missed? It even doesn't work in the same module so that's not the cause.
What am I missing?
BaseTest().someProperty = "extended"
Here you make a new BaseTest object by calling the constructor BaseTest() and you are not allowed to access protected properties of other BaseTest objects.
baseTest.someProperty = "extended"
the static BaseTest object is also another object and not the Extended object itself.
Being protected merely makes it possible to do
someProperty = "extended"
or the equivalent
this.someProperty = "extended"
That is, access the property of this object.
I believe the protected modifier doesn't work like that in Kotlin.
The documentation says:
The protected modifier is not available for top-level declarations.
But I agree it's quite confusing as written. It appears the documentation focuses more on the Outter/Inner class relationship via the this keyword.

Kotlin: data class private setter public getter

Is there any way I can make a private setter and a public getter in a Kotlin Data Class?
data class Test(var attribute: String) {
// attribute can be mutated inside this class
// but outside only readable ?
}
A simple approach would be to have a private var, but then to provide a public property that delegates to it:
data class Test (private var attribute_ : String) {
val attribute: String get() = attribute_
}
To add some background to the other answer:
There's no way to do this directly in the constructor, though there have been several proposals as to how it could be added to the language; see here.
If it weren't a data class, I'd suggest this alternative:
class Test(_attribute: String) {
var attribute = _attribute
private set
}
That only stores one value in the object, so is marginally more efficient.
But since this is a data class, that's not possible.  (Data classes can't have non-properties in their primary constructors.)  So the other answer's suggestion seems best.

Testing an injected config with spring without spring test runner

Given the following class:
public class ClassToBeTest{
${property.utility}
private String property;
private Utility utility;
public ClassToBeTested(Utility utility){
this.utility = utility;
}
public void doSomething(){
utility.doSomething(property);
}
}
We want to Mock Utility (we are using Mockito for instance) and verify that utility.doSomething is called passing the property parameter.
We don't really care about the config value (we have other tests for that). But we don't want to open the class with a method like (or passing the property by constructor).
public void setPropertyForTest(String property){
this.property = property;
}
Is there other ways to check that this private property (with no value) is passed to Utility?
Thanks a lot.
If you just want to set the private field, Spring (not Sprint) provides support for that in the spring-test module. See the setField() variants in ReflectionTestUtils.
Regards,
Sam

Auto Property with public getter and private setter

NOTE: This is not a duplicate of VB.NET equivalent of C# property shorthand?. This question is about how to have different access rights on getter and setter of a VB auto-property; e.g public getter and private setter. That question is about the syntax for auto-property (and does not mention this issue).
I am trying to convert an auto Property (public getter and private setter) from C# to VB.NET.
But after conversion VB.NET is maintaining a private field.
C# code
class DemoViewModel
{
DemoViewModel (){ AddCommand = new RelayCommand(); }
public ICommand AddCommand {get;private set;}
}
VB.NET equivalent from code converter is
Class DemoViewModel
Private Sub New()
AddCommand = New RelayCommand()
End Sub
Public Property AddCommand() As ICommand
Get
Return m_AddCommand
End Get
Private Set
m_AddCommand = Value
End Set
End Property
Private m_AddCommand As ICommand
End Class
VB.NET code generates private backing field.
Is it possible to get rid of this back field in source code (like c#)? How?
Without this feature, VB.NET source will have lots of such redundancy.
Using VB.NET, if you want to specify different accessibility for the Get and Set procedure, then you cannot use an auto-implemented property and must instead use standard, or expanded, property syntax.
Read MSDN: https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/procedures/auto-implemented-properties
If getter and setter have same accessibility, e.g. both are Public, then you can use the auto-property syntax, e.g.:
Public Property Prop2 As String = "Empty"
In VB.NET it's
Public ReadOnly Property Value As String
Then to access the private setter, you use an underscore before your property name
Me._Value = "Fred"
since the answer(s) above hold(s), you may introduce a Public Prop to expose the Private one. This may not be a nice solution but still less code, than expanded Property syntax
Private Property internalprop as object
Public Readonly Property exposedprop as Object = internalprop

If an interface defines a ReadOnly Property, how can an implementer provide the Setter to this property?

Is there a way for implementers of an interface where a ReadOnly property is defined to make it a complete Read/Write Property ?
Imagine I define an interface to provide a ReadOnly Property (i.e., just a getter for a given value) :
Interface SomeInterface
'the interface only say that implementers must provide a value for reading
ReadOnly Property PublicProperty As String
End Interface
This means implementers must commit to providing a value. But I would like a given implementer to also allow setting that value. In my head, this would mean providing the Property's setter as part of the implementation, doing something like this :
Public Property PublicProperty As String Implements SomeInterface.PublicProperty
Get
Return _myProperty
End Get
Set(ByVal value As String)
_myProperty = value
End Set
End Property
but this will not compile as, for the VB compiler, the implementer no longer implements the interface (because it is no longer ReadOnly).
Conceptually, this should work, because, in the end, it just means Implement the getter from the Interface, and add a setter method. For "normal methods", this would be no problem.
Is there some way of doing it, without resorting to "interface hiding" or "home-made" SetProperty() method, and style having the Property behave like a Read/Write property in the implementations ?
Thanks !
--UPDATE--
(I have moved this question to a separate Question)
My question is really : "why can't this be done in VB.NET", when the following is valid in C#.NET?" :
interface IPublicProperty
{
string PublicProperty { get; }
}
with implementation :
public class Implementer:IPublicProperty
{
private string _publicProperty;
public string PublicProperty
{
get
{
return _publicProperty;
}
set
{
_publicProperty = value;
}
}
}
Now supported in Visual Studio 2015.
What's New for Visual Basic
Readonly Interface Properties
You can implement readonly interface properties using a readwrite property. The interface guarantees minimum functionality, and it does not stop an implementing class from allowing the property to be set.
In the end, I ended up with a solution that matches my goal :
users that access via the Interface see at least a getter
users that access the implementation can Read and Write.
I did this "shadowing" the implemented property like this :
'users who access through interface see only the Read accessor
Public ReadOnly Property PublicProperty_SomeInterface As String Implements SomeInterface.PublicProperty
Get
Return _myProperty
End Get
End Property
'users who work with the implementation have Read/Write access
Public Property PublicProperty_SomeInterface As String
Get
Return _myProperty
End Get
Set(ByVal value As String)
_myProperty = value
End Set
End Property
Then, depending on how you use it, you can do :
Dim implementorAsInterface As SomeInterface = New InterfaceImplementor()
logger.Log(implementor.PublicProperty) 'read access is always ok
implementor.PublicProperty = "toto" 'compile error : readOnly access
Dim implementor As InterfaceImplementor = New InterfaceImplementor()
implementor.PublicProperty = "toto" 'write access
There is nothing at a CLI level which prevents this type of implementation and as you've demonstrated it's already supported by C#. The VB.Net language just doesn't support this style of implementation.
Knowing why though is a bit tough since the decision is almost 10 years removed at this point. Very likely it was just an over site at the time interface implementation was designed.
You can't do it as the interface requires that you implement a ReadOnly Property.
Properties don't allow overloading so there is no way to implement a non-ReadOnly and also a ReadOnly.
I would suggest you either implement a Custom Setter or drop the ReadOnly from the Interface.
Without details of why you want to do this it is hard to suggest the best solution
In Visual Basic, when you implement a method or property from an interface, you can change its name and its visibility. You can leverage that capability to handle the case you are asking about. Prior to Visual Studio 2015, I often did this:
Interface:
Public Interface SomeInterface
ReadOnly Property SomeProperty As String
End Interface
Implementing Class:
Public Class SomeClass
Implements SomeInterface
Public Property SomeProperty As String
Private ReadOnly Property SomeProperty_ReadOnly As String Implements SomeInterface.SomeProperty
Get
Return Me.SomeProperty
End Get
End Property
End Class
The result is that SomeProperty is read-only when accessed through SomeInterface, but read-write when accessed through SomeClass:
Dim c As New SomeClass
c.SomeProperty = "hello" 'Write via class OK
Dim s1 = c.SomeProperty 'Read via class OK
Dim i As SomeInterface = c
Dim s2 = i.SomeProperty 'Read via interface OK
i.SomeProperty = "greetings" 'Syntax Error, interface property is read-only