Object Initializers, Non-Public Children, and Nested Initialization - c#

I was looking through my codebase and found a line of code that R# had helpfully refactored for me. Here's a representative sample:
public class A
{
public B Target { get; private set; }
public object E { get; set; }
public A()
{
Target = new B();
}
}
public class B
{
public object C { get; set; }
public object D { get; set; }
}
public static class Test
{
static A LocalA;
static void Initialize()
{
LocalA = new A
{
E = "obviously this should be settable",
Target =
{
C = "Whoah, I can set children properties",
D = "without actually new-ing up the child object?!"
}
};
}
}
Essentially, initialization syntax allows for setting a child object's public properties without actually performing the constructor call (obviously if I pull the Target constructor call from the constructor of A, the whole initialization fails due to a null reference.
I've searched for this, but it's difficult to put into Google-able terms. So, my question is: (a) what is this called exactly, and (b) where can I find some more information in C# documentation about it?
Edit
Looks like someone else has asked this with similar lack of documentation found:
Nested object initializer syntax

There is nothing concrete in the documentation that I see on this topic of Object Initializers, but I did decompile the code, and here is what it actually looks like once decompiled:
A a = new A();
a.E = "obviously this should be settable";
a.Target.C = "Whoah, I can set children properties";
a.Target.D = "without actually new-ing up the child object?!";
Test.LocalA = a;
A known fact on Object Initializers is that they always run the constructor first. So, that makes the above code work. If you remove the initialization of Target in the constructor of A you will get an exception when the property initializers are tried since the object was never instantiated.

This might not be the answer and I agree its really difficult to put this into a language that google understands
In this case you are assigning values to C and D which are public properties of Target object
LocalA.Target.C = "Whoah, I can set children properties";
LocalA.Target.D = "without actually new-ing up the child object?! Nope I dont think so:)!"
You are not actually initializing a new B() as the Target setter is Private. This is obviously going to fail if B is not initialized.

Related

Is it possible to assign a property of a class assigning it to the instance of that class?

To further explain: i have a class let's say A, with a property of type let's say X; what i would like to do is to be able to instantiate A somewhere and assign the attribute using the instance without accessing the property itself or using methods, and possibly doing some other operation. Something like this:
public class A
{
private X _inside; //it actually can be public also
private DateTime _timeStamp;
public A() {X = new X();}
}
A anInstance = new A();
X aParameter = new X();
anInstance = aParameter
aParameter should be set to the _inside property of anInstance, while also assign DateTime.UtcNow to _timeStamp. Is it possible to do so? I am aware that doing so through a method or get and set is way easier, i'd get the same result and is possibly more efficient, but i would like to do so.
Also, I don't know if this thing has a specific name, therefore this question may be a duplicate; I am highlighting this because i had a problem with circular headers once but i didn't know that they were called so and my question was marked as a duplicate (not an english native seaker), which is not a problem as long as pointing we have an answer.
Anyway, thanks in advance!
Edit lexicon fixed as suggested in the comments
I believe what you're asking for is similar to VB classic's default properties1. Imagine that C# (and .NET in general) had adopted this concept, and that we're allowed to declare one2:
//Not legal c#
public class A
{
public default A _inside {get;set; }
private DateTime _timeStamp;
public A() {}
}
It's perfectly legal for classes to have properties of their own types, and introducing restrictions just for these default properties to avoid the problems I'm about to talk about are worse than disallowing the existence of these default properties3.
So you now have the code:
A anInstance = new A();
A aParameter = new A();
anInstance = aParameter;
Pop quiz - what does line 3 do? Does it assign _inner? Of does it reassign anInstance?
VB classic solved this issue by having two different forms of assignment. Set and Let. And it was a frequent source of bugs (Option Explicit being off by default didn't help here either).
When .NET was being designed, the designers of both C# and VB.Net looked at this and said "nope". You can have indexers (c#)/default properties (VB.Net) but they have to have additional parameters:
public class A
{
private Dictionary<int,A> _inner = new Dictionary<int,A>();
public A this[int i] {
get { return _inner[i]; }
set { _inner[i] = value; }
}
private DateTime _timeStamp;
public A() {}
}
And now we can disambiguate the different assignments in a straightforward manner:
A anInstance = new A();
A aParameter = new A();
anInstance = aParameter;
anInstance[1] = aParameter;
Lines 3 and 4 are, respectively, reassigning the reference and reassigning the property value.
1VB.Net does have default properties but, as discussed later, they're not precisely the same as VB classic's.
2Note that we can't assign it an instance in the constructor now - that would lead to a stack overflow exception since constructing any instance of A would require constructing an additional instance of A which would require constructing an additional instance of A which would...
3A concrete example of this would be a Tree class that has subtrees and a SubTree class that inherits from Tree and has a Parent property of tree. If that were the "default property" for the SubTree class you'd encounter these same property/reference assignment issues discussed lower down if trying to assign a parent of a subtree of a subtree.
Which basically means that you have to disallow default properties of both the actual type in which it's declared and any type to which it's implicitly convertible, which includes all types in its inheritance hierarchy.
Did you think about inheritance?
public class A : X
{
private DateTime _timeStamp;
public A() : base() {}
}
A anInstance = new A();
X aParameter = new X();
anInstance = (A)aParameter;

Is there any way to implement a get method inside a class in C#?

I would like to know if there is any way to implement a get method inside a class?
public class Element: IWebElement
{
IWebElement realElement;
//Question point is this get{}
//Everytime I access the instance of this class this get would be called
get
{
//This 'realElement' is not present yet
//So I cannot initialize it
//But when the properties of this class are accessed
//I'm telling the get method that it's time to initialize 'realElement'
realElement = webDriver.FindElement(...);
Visible = element.Visible;
return this;
}
public bool Visible {get; set;}
}
public class AnotherClass()
{
public void AccessElement()
{
Element element = new Element();
if(element.Visible) // At this point the 'element'
{
}
}
}
Usage:
I cannot initialize every property with their own get, because they are too many
Everytime I access the instance of this class this get would be called
If that could be done you'd be in trouble returning this since that would then access the instance, which would call the method, which would then access the instance, which would call the method… and so on until you get a StackOverflowException (or if it got tail-call optimised, forever).
More generally the question doesn't make sense.
A get method is a method identified as being the getter of a property. When C# is compiled to CIL then properties with getters are compiled so that there is a .property declaration with a .get declaration that refers to that method. If C# decided to change the rules to have getters on classes, it wouldn't have any corresponding CIL to compile it to.
The closest thing to a getter on a class in .NET is a default property, which in C# you can only have (and will always have) on a property called this (it becomes what is visible to other .NET languages or reflection property called Item), but it must have an indexer, and it does still exist as a property rather than with the getter directly applied to the class.
You could use the constructor, so it will be called everytime instance of object will be created.
public class Element()
{
public Element(){
AnyProperty = ""; //some value initialize
}
}
Added this new answer with my old answer because I got downvoted for trying to answer your original code which is now really different. Sheesh.
Usage: I cannot initialize every property with their own get, because
they are too many
So, this is actually not how you usually use get. Get is used mostly for access to a private method, or with a little logic, and oftentimes for data-binding such as in MVVM, etc.
I think your wording is not accurate. You said
Everytime I access the instance of this class this get would be called
But based on your code, what you mean is "Everytime I instantiate a class". The only thing you really need is a constructor.
public class Element: IWebElement
{
IWebElement realElement;
public bool Visible {get; set;}
public Element()
{
realElement = webDriver.FindElement(...);
Visible = element.Visible;
}
}
Old answer:
You're probably thinking of the Singleton Pattern
EDIT: This originally answered original question's code, seen below.
public class Element()
{
//Question point is this get{}
//Everytime I access the instance of this class this get would be called
get{
return this;
}
public string AnyProperty {get; set;}
}
public class AnotherClass()
{
public void AccessElement()
{
Element element = new Element();
element.AnyProperty = "";
}
}

Property initializers vs old way of initializing property .Can you clarify

googled but could not find an explanation of usage for property initializers
Could somebody tell me if below code is the same?are properties that uses property initializers only instantied once?
what is the difference between these 3 ways of initialize a list in terms of efficiency and best practice
1) private List<Address>Addresses
{
get
{
return addresses ?? (addresses = new List<Address>());
}
}
2) public List<Address> Addresses{ get; set; } = new List<Address>();
3) within constructor Addresses= new List<Address>()
thanks for clarifation!
Examples 2 and 3 initialize the property as soon as each instance is created.
Example 1 initializes the property lazily; it does this by initializing the backing field only at the first invocation of the property getter (when the backing field is still uninitialized). It's entirely possible that the backing field remains uninitialized for the entire lifetime of a given instance provided that instance's Addresses property is never accessed.
Whether or not lazy initialization is more efficient depends entirely on the property and how it's going to be used.
The pre-C# 6 equivalent of example 2 is not lazy initialization, but the following:
public List<Address> Addresses { get; set; }
... with initialization being done in the constructor. Declaring and initializing an auto-implemented property in the same statement is new to C# 6.
First of all, do not use concrete implementation of class for property, use interface (IList, for example). Secondly, I prefer to initialize property as your Addresses inside default constructor and then call this constructor from another.
For example:
public class MyClass1
{
public IList<MyPropertyClass1> Property1{get; protected set;}
public MyPropertyClass2 Property2{get; protected set;}
...
public MyClass1()
{
//I initialize Property1 by empty List<T>=> internal logic will not crashed if user try to set Property1 as null.
Property1=new List<MyPropertyClass1>();
Property2=default(MyPropertyClass2);
...
}
public MyClass1(IList<MyPropertyClass1> property1, MyPropertyClass2 property2)
:this()
{
if(property1!=null)
{
Property1=property1;
}
if(property2!=default(MyPropertyClass2))
{
Property2=property2;
}
}
}

"Writable" reference to object

Not sure I'm able to formulate this question in a way someone would simply understand, so lets have a cool marketing example:
public class Part
{
public MemberType member;
...
}
public class Product
{
public Part part1;
...
}
...
Product product = new Product();
I need to modify the public product's part1. So, the natural method is to write something like:
product.part1 = new Part();
Now, an algorithm (let's say a sort of search one) would go through the product object and identify the part1 as an interesting part and returns reference to it:
Part Search(Product product)
{
Part part = null;
...
part = product.part1;
...
return part;
}
...
interesting_part = Search(product);
We can alter the product object via the interesting_part like
interesting_part.member = whatever;
Now, the question: in c/c++ if the Product.part1 is pointer to Part and Search returns address of this pointer, we could replace the part1 just by assigning new value to this address. AFAIK this is not possible for c# reference:
interesting_part = new Part();
Just creates new object and copies its reference to the interresting_part, but without knowing the member parent (product object), we are not able to modify the (product.part1) reference, just its content. We would need second level of the reference.
Is there something like "ref reference" type which would accept reference addresses? In such hypothetical case the search would return ref Part and assigning to such value would replace the referenced object with the new one.
Thanks.
You could create a Reference class
class Reference<T>
{
private Func<T> m_Getter;
private Action<T> m_Setter;
public Reference(Func<T> getter, Action<T> setter)
{
m_Getter = getter;
m_Setter = setter;
}
public T Value
{
get{return m_Getter();}
set{m_Setter(value);}
}
}
Now you can say
Reference<Part> Search(Product product)
{
Part part = null;
...
part = product.part1;
var reference=new Reference<Part>(()=>product.part, (value)=>product.part1=value);
return refernce;
}
var partReference = Search(product);
partReference.Value = someNewPart;
In a very similar situation, I keep a reference of the parent in each child object. Simple and works.
public class Part
{
public MemberType member;
...
public Product parent;
Part(Product p)
{
parent = p;
}
}
public class Product
{
public Part part1;
...
}
I don't think you can do that. You would need to mutate a reference to you product object, or have some other added layer of reference.
So you need to build a Proxy object. The Product would get a reference to the Proxy and the (hidden) Part can be exchanged. This is a common OO design pattern. Of course the Proxy can delegate method calls to the Part.
If you want to change the field, you can do this,
class Program
{
static void Main(string[] args)
{
var holder = new Holder();
holder.CurrentPart = new Part() { Name = "Inital Part" };
Console.WriteLine(holder.CurrentPart.Name);
TestRef(ref holder.CurrentPart);
Console.WriteLine(holder.CurrentPart.Name);
Console.ReadKey();
}
public static void TestRef(ref Part part)
{
part = new Part() { Name = "changed" };
}
}
public class Part
{
public string Name;
}
public class Holder
{
public Part CurrentPart;
}
This won't work with property, indexers and so.
As far as I know, there isn't any way to alter an object's "parent" without having a reference to it. So I believe the official answer to your question as written is "no".
That said, there are many ways to accomplish the task as written. The easiest option is to add a reference to the parent from the part object. You end up with something like:
public class Part
{
public Product parentProduct;
public MemberType member;
...
}
Now whenever you have a part object you also know what product the part goes with (IF it does indeed go with a part at all). This is not necessarily a bad coding style but there certainly are pitfalls. You can update the product, but forget to update the parts in that product, you are coding so that parts have one product, but what if that part has many products? You can see how this works, but it can get complicated.
Taking this and making it more generic you can have reference the parent as an object type. That looks like:
public class Part
{
public object parent;
public MemberType member;
...
}
Now when you want to use the parent you can write something like:
var parentProduct = myPart.parent as Product;
This will convert the parent to a product or will assign null if the parent is not of the type Product. Now parts can have parents of any given type you would want and you have made the pattern more flexible.
One final pattern I know people use frequently is delegates. This allows you to pass in a function effectively modifying the way "search" is working. Say what you really want to do is search, then process the results in some manner, but you want that processing to be flexible (this may be what you were doing with the results). In that case, you can use delegates as follows:
// define the delegate
public delegate void ProcessResultDelegate(Product result, Part interestingPart);
// an example search function
public static void RunSearch(IEnumerable<Product> products, ProcessResultDelegate processingHelper)
{
// run the search... then call the processing function
processingHelper(searchResult, interestingPart);
}
This pattern is more useful when you want to modify the behavior of a routine rather than the return value from that routine.
Anyways, hope these patterns help some!

Should a protected property in a C# child class hide access to a public property on the parent?

I have the following code:
public class Parent
{
public string MyField { get; set; }
}
public class Child : Parent
{
protected new int MyField { get; set; }
}
I try and access this with:
static void Main(string[] args)
{
Child child = new Child();
child.MyField = "something";
}
Visual studio 2008 compiles this without comment, but under Mono (2.4.2, Ubuntu) I get the error message
'HideTest.Child.MyField' is inaccessible due to its protection level (CS0122)
Is one implementation or the other more compliant with the standard here?
Edit: Thanks to all the people who have pointed out the bad design. Unfortunately it's a third-party library and changing it significantly isn't practical.
From ECMA-334 (the C# spec) §10.7.1.2 :
A declaration of a new member hides an inherited member only within the scope of the new member.
You can see this behavior by running this test on Microsoft's implementation.
using System;
using NUnit.Framework;
namespace ScratchPad
{
[TestFixture]
public class Class1
{
[Test]
public void InheritanceHiding()
{
var b = new Base();
var d = new Derived();
var baseSomeProperty = b.SomeProperty;
var derivedSomeProperty = d.SomeProperty;
b.GetSomeProperty();
d.GetSomeProperty();
}
}
public class Base
{
public string SomeProperty
{
get
{
Console.WriteLine("Getting Base.SomeProperty");
return "Base.SomeProperty";
}
}
public string GetSomeProperty()
{
return SomeProperty;
}
}
public class Derived : Base
{
protected new int SomeProperty
{
get
{
Console.WriteLine("Getting Derived.SomeProperty");
return 3; //Determined by random roll of the dice.
}
}
public new int GetSomeProperty()
{
return SomeProperty;
}
}
}
Which will output:
Getting Base.SomeProperty //(No Controversy)
Getting Base.SomeProperty //(Because you're calling from public scope and the new member is in protected scope, there is no hiding)
Getting Base.SomeProperty //(No Controversy)
Getting Derived.SomeProperty //(Now because you're calling from protected scope, you get the protected member).
So the property you're accessing from your Main() should be the base class property (as it is in MS.NET), not the derived property (as in Mono), because the new derived member only hides the 'old' base member in protected scope.
Mono is doing something wrong here according to the spec.
Jason's answer is correct but he asks for a justification of this behaviour. (Namely that a hiding method is only hiding within the scope of the hiding method.)
There are a number of possible justifications. One in particular is that this is yet another way in which the design of C# mitigates the Brittle Base Class problem.
FooCorp makes Foo.DLL:
public class Foo
{
public object Blah() { ... }
}
BarCorp makes Bar.DLL:
public class Bar : Foo
{
// stuff not having to do with Blah
}
ABCCorp makes ABC.EXE:
public class ABC
{
static void Main()
{
Console.WriteLine((new Bar()).Blah());
}
}
Now BarCorp says "You know, in our internal code we can guarantee that Blah only ever returns string thanks to our knowledge of our derived implementation. Let's take advantage of that fact in our internal code."
public class Bar : Foo
{
internal new string Blah()
{
object r = base.Blah();
Debug.Assert(r is string);
return (string)r;
}
}
ABCCorp picks up a new version of Bar.DLL which has a bunch of bug fixes that are blocking them. Should their build break because they have a call to Blah, an internal method on Bar? Of course not. That would be terrible. This change is a private implementation detail that should be invisible outside of Bar.DLL.
In general, the .NET implementation of C# should probably be considered "canon". From the documentation on the new Modifier:
A constant, field, property, or type introduced in a class or struct hides all base class members with the same name.
... it seems like the Mono implementation is more correct given this definition. It should be hiding the implementation of MyField in the Parent class, and therefore it should only be accessible with the int MyField signature from the Child class.
Prelude: This code is crazy. If you actually have code in your app like this, fix it now. Either make them both protected or both public!
Regarding the error: The CLR has a lot of really strange 'edge case' rules in it for dealing with things like this. The best place to look for this kind of stuff is usually Eric Lippert's blog.
In saying that though, it looks like mono is actually doing the more sensible thing here in my opinion.
On second look, the C# one makes more sense once you factor in the 'behind the scenes' stuff.
Properties are not "first class" in MSIL. A property in C# or VB is just compiled down to a get and set method (the compiler also sticks an attribute somewhere for bookkeeping).
int MyField { get; set; } will actually produce MSIL for two methods:
void set_MyField(int value);
int get_MyField();
Now, given that your new method has a different type, you'll end up with the following 2 setter methods.
void set_MyField(int value);
void set_MyField(string value);
When you call x.MyField = "string" you're just calling one of those methods. This then boils down to a normal method overloading scenario. It's perfectly valid to have two methods with the same name that take different parameters, so the compiler will just select the string one and carry on it's merry way.
So yeah. The C# one makes sense if you know how the internals work, the Mono one makes more sense if you don't.
Which one is "more correct"? Ask Eric Lippert :-)
Just adding my 2 cents) That's a Mono bug, here is the description.
IMHO the difference is that MS.NET recognize the type string for MyField and sets the value of Parent property and in Mono in just tries to access MyField in Child class.
You are making something that's available through the base class unavailable through the child. You can try that, but it won't actually do anything. People can always just do this:
Parent child = new Child();
and call the method. So if you want the field to be hidden, declare a new one and keep the inherited one public.

Categories

Resources