Setting value of inherited trivial property in the constructor triggers Code Analysis Warning CA2214 - c++-cli

I define an interface containing a trivial/simple property and an implementing class that sets the property in its constructor:
interface class IMyInterface
{
public:
property System::String^ MyName;
};
ref class MyImplementingClass : public IMyInterface
{
public:
virtual property System::String^ MyName;
MyImplementingClass()
{
MyName = "Test Name";
}
};
This doesn't seem too contentious, but when I run Code Analysis in Visual Studio 2019 using the default 'Microsoft Mixed (C++/CLR) Recommended Rules' ruleset it triggers warning CA2214:
warning CA2214: Microsoft.Usage : 'MyImplementingClass::MyImplementingClass(void)' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences:
warning CA2214: MyImplementingClass..ctor()
warning CA2214: MyImplementingClass.set_MyName(String):Void
So I think it's complaining because setting this property involves calling the automatically implemented method set_MyName() and since that method is virtual it is considered a violation to call it from a constructor.
Does that mean this whole pattern is invalid?
What is the correct way to set the value of an inherited property at construction time?

Related

In ASPNetCore 2.2, Startup.cs, the Configure property only has {get}, yet it is assigned a reference. Why is this? [duplicate]

I created an automated property:
public int Foo { get; }
This is getter only.
But when I build a constructor, I can change the value:
public MyClass(string name)
{
Foo = 5;
}
Why is it possible, even though this is get-only?
This is a new C# 6 feature, "Getter-only auto-properties", also known as "Auto-Property Initializers for Read-Only Properties" as discussed in this MSDN magazine article 'C# : The New and Improved C# 6.0' by Mark Michaelis and in the C# 6.0 draft Language Specification.
The read-only field's setter is only accessible in the constructor, in all other scenarios the field is still read only and behaves as before.
This is a convenience syntax to reduce the amount of code you need to type and to remove the need to explicitly declare a private module level variable to hold the value.
This feature was seen as important as, since the introduction of Auto-Implemented Properties in C#3, mutable properties (those with a getter and setter) had become quicker to write than immutable ones (those with only a getter), meaning people were being tempted to use mutable properties to avoid having to type the code for a backing field usually required for read-only properties. There is more discussion of Auto-Implemented properties in the relevant section of the Microsoft C# Programming Guide.
This blog post, '#1,207 – C# 6.0 – Auto-Property Initializers for Read-Only Properties' by Sean Sexton Has a good explanation and example as follows:
Prior to C# 6.0, if you wanted a read-only (immutable) property, you’d
typically use a read-only backing field that is initialized in the
constructor, as shown below.
public class Dog
{
public string Name { get; set; }
// DogCreationTime is immutable
private readonly DateTime creTime;
public DateTime DogCreationTime
{
get { return creTime; }
}
public Dog(string name)
{
Name = name;
creTime = DateTime.Now;
}
}
In C# 6.0, you can use auto-implemented properties to implement a
read-only property. You do this by using an auto-property
initializer. The result is much cleaner than the above example, where
we had to explicitly declare a backing field.
public class Dog
{
public string Name { get; set; }
// DogCreationTime is immutable
public DateTime DogCreationTime { get; } = DateTime.Now;
public Dog(string name)
{
Name = name;
}
}
More details can also be found in the dotnet Roslyn repo on GitHub:
Auto-properties can now be declared without a setter.
The backing field of a getter-only auto-property is implicitly
declared as readonly (though this matters only for reflection
purposes). It can be initialized through an initializer on the
property as in the example above. Also, a getter-only property can be
assigned to in the declaring type’s constructor body, which causes the
value to be assigned directly to the underlying field:
This is about expressing types more concisely, but note that it also
removes an important difference in the language between mutable and
immutable types: auto-properties were a shorthand available only if
you were willing to make your class mutable, and so the temptation to
default to that was great. Now, with getter-only auto-properties, the
playing field has been leveled between mutable and immutable.
and in the C# 6.0 draft Language Specification (NB: The language specification is final as far as Microsoft are concerned, but it is yet to be approved as a EMCA/ISO standard, hence the 'draft'):
Automatically implemented properties
An automatically implemented property (or auto-property for short), is
a non-abstract non-extern property with semicolon-only accessor
bodies. Auto-properties must have a get accessor and can optionally
have a set accessor.
When a property is specified as an automatically implemented property,
a hidden backing field is automatically available for the property,
and the accessors are implemented to read from and write to that
backing field. If the auto-property has no set accessor, the backing
field is considered readonly (Readonly fields). Just like a readonly
field, a getter-only auto-property can also be assigned to in the body
of a constructor of the enclosing class. Such an assignment assigns
directly to the readonly backing field of the property.
An auto-property may optionally have a property_initializer, which is
applied directly to the backing field as a variable_initializer
(Variable initializers).
This is a new feature in C#6 that allows you to create read-only properties and initialize their values from the constructor (or inline when you declare them).
If you try to change the value of this property outside the constructor, it would give you a compile error.
It is read-only in the sense that once you initialize its value (inline or inside the constructor), you cannot change its value.
If it were not possible to initialize the read-only property from the constructor (or an auto-property initializer), then it would be useless, since it would always return the default value for its type (0 for numerics, null for reference types). The same semantics applied to readonly fields in all C# versions.
To define a true getter-only property (that cannot be initialized from the constructor), you need to specify what it returns as part of the definition:
public int Foo { get { return 5; } }
Or, more concisely in C# 6:
public int Foo => 5;
“readonly automatically implemented properties”
First of all I want to clarify that the property like
public string FirstName { get; }
Is known as “readonly automatically implemented properties”
To verify this you can run & check the above code with Visual Studio. If you change the language version from C#6.0 to C#5.0 then compiler will throw the following exception
Feature 'readonly automatically implemented properties' is not available in C# 5. Please use language version 6 or greater.
to change C# language version visit here
Now I am coming to your second question
“This is getter only. But when I build a constructor, I can change the value”
Microsoft introduces the “readonly automatically implemented properties” on the logic of read only. As we know that the keyword “readonly” is available from C#1.0. we use “readonly” keyword as modifier on a field and that field can be assigned in 2 ways either at the time of declaration or in a constructor in the same class.
In the same way value of “readonly automatically implemented properties” can be assigned in 2 ways
Way1 (at the time of declaration):
public string FirstName { get; } = "Banketeshvar";
Way2 (in a constructor in the same class)
Person()
{
FirstName = "Banketeshvar";
}
Purely ReadOnly Property
If you are looking for purely Readonly property then go for this
public string FullName => "Manish Sharma";
now you cannot assign value of “FullName” propery from constructor.
If you try to do that it will throw the following exceptions
“Property or indexer 'Person.FullName' cannot be assigned to -- it is read only”
Auto property feature was added to the language during C# 3.0 release. It allows you to define a property without any backing field, however you still need to use constructor to initialize these auto properties to non-default value. C# 6.0 introduces a new feature called auto property initializer which allows you to initialize these properties without a constructor like Below:
Previously, a constructor is required if you want to create objects
using an auto-property and initialize an auto-property to a
non-default value like below:
public class MyClass
{
public int Foo { get; }
public Foo(int foo)
{
Foo = foo;
}
}
Now in C# 6.0, the ability to use an initializer with the auto-property
means no explicit constructor code is required.
public string Foo { get; } = "SomeString";
public List<string> Genres { get; } = new List<string> { "Comedy", "Drama" };
You can find more information on this here
A variable declared readonly can be written within a constructor, but in languages which honor the attribute, cannot be modified after the constructor returns. That qualifier was provided as a language feature because it is often necessary for fields whose values will vary based upon constructor parameters (meaning they can't be initialized before the constructor starts) but won't have to change after constructors return, but it was only usable for variables exposed as fields. The semantics of readonly-qualified fields would in many cases have been perfect for public members except that it's often better for classes to expose members--even immutable ones--as properties rather than fields.
Just as read-write auto-properties exist to allow classes to expose mutable properties as easily as ordinary fields, read-only auto-properties exist to allow classes to expose immutable properties as easily as readonly-qualified fields. Just as readonly-qualified fields can be written in a constructor, so too with get-only properties.

Swift readonly external, readwrite internal property

In Swift, what is the conventional way to define the common pattern where a property is to be externally readonly, but modifiable internally by the class (and subclasses) that own it.
In Objective-C, there are the following options:
Declare the property as readonly in the interface and use a class extension to access the property internally. This is message-based access, hence it works nicely with KVO, atomicity, etc.
Declare the property as readonly in the interface, but access the backing ivar internally. As the default access for an ivar is protected, this works nicely in a class hierarchy, where subclasses will also be able to modify the value, but the field is otherwise readonly.
In Java the convention is:
Declare a protected field, and implement a public, read-only getter (method).
What is the idiom for Swift?
Given a class property, you can specify a different access level by prefixing the property declaration with the access modifier followed by get or set between parenthesis. For example, a class property with a public getter and a private setter will be declared as:
private(set) public var readonlyProperty: Int
Suggested reading: Getters and Setters
Martin's considerations about accessibility level are still valid - i.e. there's no protected modifier, internal restricts access to the module only, private to the current file only, and public with no restrictions.
Swift 3 notes
2 new access modifiers, fileprivate and open have been added to the language, while private and public have been slightly modified:
open applies to class and class members only: it's used to allow a class to be subclassed or a member to be overridden outside of the module where they are defined. public instead makes the class or the member publicly accessible, but not inheritable or overridable
private now makes a member visible and accessible from the enclosing declaration only, whereas fileprivate to the entire file where it is contained
More details here.
As per #Antonio, we can use a single property to access as the readOnly property value publicly and readWrite privately. Below is my illustration:
class MyClass {
private(set) public var publicReadOnly: Int = 10
//as below, we can modify the value within same class which is private access
func increment() {
publicReadOnly += 1
}
func decrement() {
publicReadOnly -= 1
}
}
let object = MyClass()
print("Initial valule: \(object.publicReadOnly)")
//For below line we get the compile error saying : "Left side of mutating operator isn't mutable: 'publicReadOnly' setter is inaccessible"
//object.publicReadOnly += 1
object.increment()
print("After increment method call: \(object.publicReadOnly)")
object.decrement()
print("After decrement method call: \(object.publicReadOnly)")
And here is the output:
Initial valule: 10
After increment method call: 11
After decrement method call: 10

AOP - Injecting a property with a dynamically computed value

(or "Using LocationInterceptionAspect and IInstanceScopedAspect together")
Using Postsharp I'm trying to inject a property into a target class using 'IntroduceMember' and then using the 'OnGetValue' functionality of LocationInterceptionAspect dynamically give it a value on inspection.
Originally I thought that I'd need two separate aspects, one for the field injection and one for the location interception but managed to combine the two by implementing the IInstanceScopedAspect interface and inheriting from LocationInterceptionAspect.
The problem is that if I set a breakpoint I will see the property that's been injected, but if I set another breakpoint in the OnGetValue method (that gets fired for each property on the class) I can't see it...
Here's some sample code:
[Serializable]
class DALDecoratorWrapper : LocationInterceptionAspect, IInstanceScopedAspect
{
public override void OnGetValue(LocationInterceptionArgs args)
{
if (args.LocationName == "Type")
{
args.Value = "computed value here";
}
args.ProceedGetValue();
}
[IntroduceMember(OverrideAction = MemberOverrideAction.OverrideOrFail)]
public String Type { get; set; }
I was also hoping there was a better way of doing this than overriding OnGetValue as that's called for each getter where really I want to only target the getter of the property that's been injected
Cheers

Property chaining in RhinoMocks

I have a class TxRx with a property called Common. Common then has a property called LastMod. I want to write a RhinoMock expectation to show that LastMod has been set with something. So I tried:
var txRx = MockRepository.GenerateMock<TxRx>();
var common = MockRepository.GenerateMock<Common>();
txRx.Expect(t => t.Common).Return(common);
txRx.Expect(t => t.Common.LastMod).SetPropertyAndIgnoreArgument();
But I get the following exception:
System.InvalidOperationException: Invalid call, the last call has been used or no call has been made (make sure that you are calling a virtual (C#) / Overridable (VB) method).
at Rhino.Mocks.LastCall.GetOptions[T]()
at Rhino.Mocks.RhinoMocksExtensions.Expect[T,R](T mock, Function`2 action)
at ...
I presume this means Common needs to be virtual, but as it is a property on a LinqToSql generated class I can't make it virtual (other than hacking the autogen code which is not really an option).
Is there any way around this?
One possibility is to wrap TxRx in a mockable class (i.e. one that has overridable methods and properties which you wish to mock out or implements an interface which defines the properties or methods that you're interested in) and then pass around the wrapper rather than the LinqToSQL class itself.
Perhaps something like the following:
public class TxRxWrapper : ITxRxWrapper
{
private TxRx m_txrx;
public object LastMod
{
get { return m_txrx.Common.LastMod; }
}
...
}
public interface ITxRxWrapper
{
public object LastMod { get; }
...
}
Not ideal (i.e. it can get somewhat cumbersome to pass wrappers around just for mockability!) but that's the only way you can get RhinoMocks to mock properties/methods for you.
The other option is to use TypeMock instead which I believe uses a different mechanism to mock stuff out. I don't think it's free, though.
You would need to replace your second expectation with
txRx.Expect(() => common.LastMod).SetPropertyAndIgnoreArgument();
But the Common property itself needs to be virtual for this to work.

What is the purpose of hidebysig in a MSIL method?

Using ildasm and a C# program e.g.
static void Main(string[] args)
{
}
gives:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 2 (0x2)
.maxstack 8
IL_0000: nop
IL_0001: ret
} // end of method Program::Main
What does the hidebysig construct do?
From ECMA 335, section 8.10.4 of partition 1:
The CTS provides independent control
over both the names that are visible
from a base type (hiding) and the
sharing of layout slots in the derived
class (overriding). Hiding is
controlled by marking a member in the
derived class as either hide by name
or hide by name-and-signature. Hiding
is always performed based on the kind
of member, that is, derived field
names can hide base field names, but
not method names, property names, or
event names. If a derived member is
marked hide by name, then members of
the same kind in the base class with
the same name are not visible in the
derived class; if the member is marked
hide by name-and-signature then only a
member of the same kind with exactly
the same name and type (for fields) or
method signature (for methods) is
hidden from the derived class.
Implementation of the distinction
between these two forms of hiding is
provided entirely by source language
compilers and the reflection library;
it has no direct impact on the VES
itself.
(It's not immediately clear from that, but hidebysig means "hide by name-and-signature".)
Also in section 15.4.2.2 of partition 2:
hidebysig is supplied for the use of
tools and is ignored by the VES. It
specifies that the declared method
hides all methods of the base class
types that have a matching method
signature; when omitted, the method
should hide all methods of the same
name, regardless of the signature.
As an example, suppose you have:
public class Base
{
public void Bar()
{
}
}
public class Derived : Base
{
public void Bar(string x)
{
}
}
...
Derived d = new Derived();
d.Bar();
That's valid, because Bar(string) doesn't hide Bar(), because the C# compiler uses hidebysig. If it used "hide by name" semantics, you wouldn't be able to call Bar() at all on a reference of type Derived, although you could still cast it to Base and call it that way.
EDIT: I've just tried this by compiling the above code to a DLL, ildasming it, removing hidebysig for Bar() and Bar(string), ilasming it again, then trying to call Bar() from other code:
Derived d = new Derived();
d.Bar();
Test.cs(6,9): error CS1501: No overload for method 'Bar' takes '0' arguments
However:
Base d = new Derived();
d.Bar();
(No compilation problems.)
As per THE SKEET's answer, in addition the reason for this is that Java and C# allow the client of a class to call any methods with the same name, including those from base classes. Whereas C++ does not: if the derived class defines even a single method with the same name as a method in the base class, then the client cannot directly call the base class method, even if it doesn't take the same arguments. So the feature was included in CIL to support both approaches to overloading.
In C++ you can effectively import one named set of overloads from the base class with a using directive, so that they become part of the "overload set" for that method name.
According to Microsoft Docs
When a member in a derived class is declared with the C# new modifier
or the Visual Basic Shadows modifier, it can hide a member of the same
name in the base class. C# hides base class members by signature. That
is, if the base class member has multiple overloads, the only one that
is hidden is the one that has the identical signature. By contrast,
Visual Basic hides all the base class overloads. Thus, IsHideBySig
returns false on a member declared with the Visual Basic Shadows
modifier, and true on a member declared with the C# new modifier.