I was experimenting in order to create a little compile-safe helper for mapping between classes.
public class A : IMappableTo<B>, IMappableTo<A>
{
public string Name { get; set; }
}
public class B
{
public string Name { get; set; }
}
public interface IMappableTo<T>
{
}
public static class ExtensionTest
{
public static T MapTo<T>(this IMappableTo<T> source)
{
return default(T); // this does not mind, just for demo purposes
}
}
The intent was to create an extension method able to detect not implemented maps (at compile time).
It worked as expected, but with an unexpected issue.
public static void test()
{
// compiler doesn't complain, but intellisense can't autocomplete it.
var case1 = new A().MapTo<A>().MapTo<B>();
var case2 = new A().MapTo<string>(); // compiler complains, as intended
}
So well, it does compile and work, but Visual Studio (tested with 2015/2017) is unable to autocomplete the extension method. I did some additional tests and it seems to be produced by the fact that class A implements two IMappableTo constructed interfaces. If I remove one, the autocomplete simply works again.
Any idea of how to fix this behaviour or rewrite the code in a manner that cause no further troubles?
is it possible to call properties after methods?
Example:
public static class Test
{
public static string Show { get; set; }
public static void Get(string s)
{
Show = s;
}
}
and call like this:
Test.Get("HI").Show;
Update 2: A fluent interface
If you are implementing a fluent interface, I would suggest renaming your methods as such:
public class Test
{
public string Show { get; set; }
public Test ConfigureShow(string show)
{
Show = show;
return this;
}
}
Your method is much more readable now and clearly defines the intent of the method:
var test = new Test()
.ConfigureShow("HI");
Make the rest of the methods in your class follow the same pattern and chain your methods on new lines for improved readability.
Update 1: What is your intent?
Is there a particular reason that you are trying to do this? There are several issues with your class:
Your methods should make sense - you should not have a method called Get which takes a parameter and then modifies the object. Generally Get methods imply that you are simply fetching something from the object.
Why are you passing in a parameter to the method, only to fetch it again?
Are you trying to implement a Fluent interface?
What is wrong with:
var show = "HI";
var test = new Test();
test.Show = show;
//You already have your text in the variable show, so why do you want to access it again?
Original answer to OP's question
public class Test
{
public string Show { get; set; }
public Test Get(string s)
{
Show = s;
return this;
}
}
I've been given a .NET project to maintain. I was just browsing through the code and I noticed this on a property declaration:
public new string navUrl
{
get
{
return ...;
}
set
{
...
}
}
I was wondering what does the new modifier do to the property?
It hides the navUrl property of the base class. See new Modifier. As mentioned in that MSDN entry, you can access the "hidden" property with fully qualified names: BaseClass.navUrl. Abuse of either can result in massive confusion and possible insanity (i.e. broken code).
new is hiding the property.
It might be like this in your code:
class base1
{
public virtual string navUrl
{
get;
set;
}
}
class derived : base1
{
public new string navUrl
{
get;
set;
}
}
Here in the derived class, the navUrl property is hiding the base class property.
This is also documented here.
Code snippet from msdn.
public class BaseClass
{
public void DoWork() { }
public int WorkField;
public int WorkProperty
{
get { return 0; }
}
}
public class DerivedClass : BaseClass
{
public new void DoWork() { }
public new int WorkField;
public new int WorkProperty
{
get { return 0; }
}
}
DerivedClass B = new DerivedClass();
B.WorkProperty; // Calls the new property.
BaseClass A = (BaseClass)B;
A.WorkProperty; // Calls the old property.
Some times referred to as Shadowing or method hiding; The method called depends on the type of the reference at the point the call is made. This might help.
https://msdn.microsoft.com/en-us/library/435f1dw2.aspx
Look at the first example here, it gives a pretty good idea of how the new keyword can be used to mask base class variables
Overloading constructors and methods seems messy, i.e. simply differentiating them by the order and number of parameters. Isn't there a way, perhaps with generics, to do this cleanly so that, even if you just have one parameter (e.g. string idCode / string status) you could still differentiate them?
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
TheForm tf1 = new TheForm("online", DateTime.Now);
TheForm tf2 = new TheForm(DateTime.Now, "form1");
}
}
public class TheForm
{
public TheForm(string status, DateTime startTime)
{
//...
}
public TheForm(DateTime startTime, string idCode)
{
//...
}
}
}
If you need that many overloads, perhaps your types are handling too much (see Single Responsibility Principle). Personally I rarely need more than one or a few constructors.
You could consider having a Fluent Builder for the class instead, although it's more work. This would allow you to write something like this:
var form = new TheFormBuilder().WithStatus("foo").WithStartTime(dt).Build();
It's more explicit, but not necessary better. It's definitely more work.
In C# 4, you can optionally write the parameter names when you invoke the constructor:
var form = new TheForm(status: "Foo", startTime: dt);
The new object initialization feature of .NET 3.0 is more flexible than an overloaded constructor. Here is a simple example:
public class Item
{
public string Name {get; set;}
public int Index {get; set;}
public string Caption {get; set;}
}
As it is written now, we can do the following in code:
var x = new item {Name=”FooBar”};
var x = new item {Name=”FooBar”, Index=”1”, Caption=”Foo Bar”};
I would only add an overloaded constructor to the class Item if I want to add functionality during property initialization. For example:
public class Item
{
public Item() {}
public Item(string name)
{
Name = name;
Caption = name; //defaulting name to caption
}
public Item(string name, int index) : this(name)
{
Index = index;
}
public Item(string name, int index, string caption) : this(name, int)
{
Caption = caption;
}
public string Name {get; set;}
public int Index {get; set;}
public string Caption {get; set;}
}
Note: If this was a child class, I could have chained to a parent constructor with the “base” keyword.
If I am writing a “configuration” type of class, I use Fluent Methods in place of Overloaded constructors.
For example, if I added these methods to the Item class:
public Item WithName(string name)
{
Name = name;
return this;
}
public Item WithIndex(int index)
{
Index = index;
return this;
}
public Item WithCaption(string caption)
{
Caption = caption;
return this;
}
I could write code like this:
var x = new Item().WithName(“FooBar”).WithIndex(“99”).WithCaption(“Foo Bar”);
The only way I can think of to differentiate the construction with a single parameter of a given type is to use a non-instance factory method, either on the type itself or in a factory class.
e.g. (on the type itself)
(untested)
public class TheForm
{
public static TheForm CreateWithId(string idCode)
{
}
public static TheForm CreateWithStatus(string status)
{
}
}
Before Fluent builders we sometimes managed to get around with parameter objects or setup objects:
public class FormSetup {
public string Status ...
public string Id ...
}
var frm = new MyForm(new FormSetup { Status = "Bla", ... });
Constructor Forwarding!
Use helper initialization classes to communicate the semantics of your overloads.
So, for instance, define
public class TheForm
{
public class TheForm(ById initializer)
{
//...
}
public class TheForm(ByStatus initializer)
{
//...
}
// ...
public class ById
{
public ById(DateTime startTime, string idCode)
// ...
}
public class ByStatus
{
public ByStatus(string status, DateTime startTime)
// ...
}
}
However, prefer using classes which are more generally usable if you can, not just for initalialization. You may want to factor your classes in a different way instead. I sense the possibility of a code smell: does your TheForm class contain too much business logic? Might you want to split out an MVC Controller, for instance?
In C# (like in many other programming languages) in this case you should use Factory Methods. Something like this:
class TheForm
{
public static TheForm CreateFromId(string idCode);
public static TheForm CreateFromStatus(string status);
}
or fiction parameters:
class TheForm
{
public TheForm(string idCode, int);
public TheForm(string status);
}
Or you can use Eiffel ;):
class THE_FORM create
make_from_id, make_from_status
feature
...
end
We use properties instead of overloading constructors, it's quite clean and easy to implement:
public class x {
public string prop1 {get;set;}
public DateTime prop2 {get;set;}
...
}
and then fill just the properties you need at instantiation time (and/or later)
var obj = new x() {
prop1 = "abc",
prop2 = 123
};
The benefit with this is it works with .Net 3.5 and makes it really clear what is being set. (as opposed to var obj = new x("abc", 123, true, false, ... etc) where you have to guess the meaning of each value, which can get really hairy when there are many overloads)
Here's an example:
Timespan.FromMilliseconds(double)
Timespan.FromSeconds(double)
Timespan.FromMinutes(double)
Timespan.FromHours(double)
Timespan.FromDays(double)
Isn't this where inheritence comes in?
Just have TheForm as a base class and then TheFormWithID and TheFormWithStatus child classes.
Have their constructors take string ID and string Status respectively passing back the DateTime value to the base class.
I haven't got any coding tools infront of me so please excuse the syntax. I'm sure that you'll figure it out.
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
TheForm tf1 = new TheFormWithStatus(DateTime.Now, "online");
TheForm tf2 = new TheFormWithID(DateTime.Now, "form1");
}
}
public class TheForm
{
public TheForm(DateTime startTime)
{
//...
}
}
public class TheFormWithID : TheForm
{
public TheFormWithID (DateTime startTime, string idCode) : TheForm (startTime)
{
//...
}
}
public class TheFormWithStatus : TheForm
{
public TheFormWithStatus (DateTime startTime, string status) : TheForm (startTime)
{
//...
}
}
}
Or have TheForm as an abstract class.
Whether you're talking about constructors or not, overloading's pretty limited, and when you start to run up against its limits, that's a hint that it's not the right tool for the job.
It's worth looking at a well-designed API that uses overloading to get a sense of what kind of job the tool is good for. XmlReader.Create is a good example: It supports twelve different overloads. Twelve! And yet, it's actually completely sensible: when you look at them all, they boil down to what would, in Python, be a single calling signature with optional parameters:
XmlReader.Create(input [, settings [, parser_context]])
input, to this method, can be a string containing a URL or filename, a TextReader, or a Stream. But irrespective of its data type, it's still fundamentally the same thing: the source of the data that the XmlReader is going to read.
Now let's look at your case. Forget about data types for a moment. There's clearly some functional difference between a status and an idCode in your application. Your form is going to behave one way if it's given a status and another if it's given an idCode. The API that you're proposing conceals this functional difference. It should be illuminating it.
I would first consider the simplest possible approach, which uses no overloads at all:
TheForm(string idCode, string status)
Make your constructor throw an exception if both values are provided (or if both are null). Note that they're mutually exclusive in the documentation. Call it a day.
My second choice would be:
enum FormType
{
IdCode,
Status
};
TheForm(FormType type, string data)
This is less concise, but it has the very great merit of making the fact that this method supports multiple mutually-exclusive modes explicit.
I called that enum FormType because it seemed like a sensible name, given what I know so far, and the fact that this method's a constructor. But whenever you contemplate creating an enum to determine the type of an instance, you should at least consider the possibility that you should really be creating a type to determine the type of an instance:
class TheFormWhatUsesIdCode : TheForm {...}
class TheFormWhatUsesStatus : TheForm {...}
The functional difference between idCode and status probably relates to a functional difference between a form instantiated with idCode and a form instantiated with status. And that strongly suggests that they should be subclasses.
In all of this analysis, I've never once considered the possibility of doing what you actually asked for, which is to provide multiple overloads. I don't think overloading is the right tool for this job. If idCode were an int and status were a string I still wouldn't think that overloading were the right tool for this job, though I probably wouldn't have ended up noticing it until I had a lot of code I needed to refactor.
I am not getting what "messy" you found in multiple constructors. I felt the static methods for returning an instance of the object also a probable alternate.
But, if somebody want to have the fancy of a single constructor and still have different implementations, we can think of passing an object derived from some interface as the input to the constructor and might check the type of the input to create an instance. This is kind of an abstract factory in this case.
In one place we have a class like the following:
using System;
namespace MyApplication
{
class Program
{
static void Main(string[] args)
{
base1 t1 = new type1();
class1 c1 = new class1(t1);
base1 t2 = new type2();
class1 c2 = new class1(t2);
//.....
}
}
public class class1
{
public class1(base1 mytype)
{
switch(mytype.type)
case mytype.types.type1
return createObjectOftype1();
case mytype.types.type2
return createObjectOftype2();
case mytype.types.type3
return createObjectOftype3();
}
public class1 createObjectOftype1()
{
//....
}
public class1 createObjectOftype2()
{
//...
}
public class1 createObjectOftype2()
{
//...
}
}
public class base1
{
publlic Enum Types {0 "type1",....
}
public class type1:base1
{
//.....
}
public class type2:base1
{
//.....
}
}
I personally dont like the idea of other classes being able to set my properties
so this allows my properties to be protected or private, but still have alot of the functionality described by other answers:
public class FooSettings
{
public bool Prop1 { get; set; }
public bool Prop2 { get; set; }
public TimeSpan Prop3 { get; set; }
public FooSettings()
{
this.Prop1 = false;
this.Prop2 = false;
this.Prop3 = new TimeSpan().ExtensionMethod(CustomEnum.Never);
}
public FooSettings BoolSettings
(bool incomingFileCacheSetting, bool incomingRuntimeCacheSetting)
{
this.Prop1 = incomingFileCacheSetting;
this.Prop2 = incomingRuntimeCacheSetting;
return this;
}
public FooSettings Prop3Setting
(TimeSpan incomingCustomInterval)
{
this.Prop3 = incomingCustomInterval;
return this;
}
public FooSettings Prop3Setting
(CustomEnum incomingPresetInterval)
{
return this.Prop3Setting(new TimeSpan().ExtensionMethod(CustomEnum.incomingPresetInterval));
}
}
public class Foo
{
public bool Prop1 { get; private set; }
public bool Prop2 { get; private set; }
public TimeSpan Prop3 { get; private set; }
public CallTracker
(
FooSettings incomingSettings
)
{
// implement conditional logic that handles incomingSettings
}
}
could then be consumed as:
FooSettings newFooSettings = new FooSettings {Prop1 = false, Prop2 = true}
newFooSettings.Prop3Setting(new TimeSpan(3,0,0));
Foo newFoo = new Foo(newFooSettings)
or
FooSettings newFooSettings = new FooSettings()
.BoolSettings(false, true)
.Prop3Setting(CustomEnum.Never)
Foo newFoo = new Foo(newFooSettings)
obviously a bit overkill for a simple class, but it gives alot of control over the types of data that can be funneled down to a single property, IE: TimeSpan can be parsed from a custom enum type using an extension method
When is it run? Does it run for each object to which I apply it, or just once? Can it do anything, or its actions are restricted?
When is the constructor run? Try it out with a sample:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Creating MyClass instance");
MyClass mc = new MyClass();
Console.WriteLine("Setting value in MyClass instance");
mc.Value = 1;
Console.WriteLine("Getting attributes for MyClass type");
object[] attributes = typeof(MyClass).GetCustomAttributes(true);
}
}
[AttributeUsage(AttributeTargets.All)]
public class MyAttribute : Attribute
{
public MyAttribute()
{
Console.WriteLine("Running constructor");
}
}
[MyAttribute]
class MyClass
{
public int Value { get; set; }
}
And what is the output?
Creating MyClass instance
Setting value in MyClass instance
Getting attributes for MyClass type
Running constructor
So, the attribute constructor is run when we start to examine the attribute. Note that the attribute is fetched from the type, not the instance of the type.
The constructor is run every time the GetCustomAttributes is invoked, or whenever some other code invokes the constructor directly (not that there's a good reason to do so, but it's not impossible either).
Note that at least in .NET 4.0, the attribute instances are not cached; a fresh instance is constructed every time GetCustomAttributes is called:
[Test]
class Program
{
public static int SomeValue;
[Test]
public static void Main(string[] args)
{
var method = typeof(Program).GetMethod("Main");
var type = typeof(Program);
SomeValue = 1;
Console.WriteLine(method.GetCustomAttributes(false)
.OfType<TestAttribute>().First().SomeValue);
// prints "1"
SomeValue = 2;
Console.WriteLine(method.GetCustomAttributes(false)
.OfType<TestAttribute>().First().SomeValue);
// prints "2"
SomeValue = 3;
Console.WriteLine(type.GetCustomAttributes(false)
.OfType<TestAttribute>().First().SomeValue);
// prints "3"
SomeValue = 4;
Console.WriteLine(type.GetCustomAttributes(false)
.OfType<TestAttribute>().First().SomeValue);
// prints "4"
Console.ReadLine();
}
}
[AttributeUsage(AttributeTargets.All)]
class TestAttribute : Attribute
{
public int SomeValue { get; private set; }
public TestAttribute()
{
SomeValue = Program.SomeValue;
}
}
It is not the best idea to have attributes behave like this, of course. At the very least, note that GetCustomAttributes is not documented to behave like this; in fact, what happens in the above program is not specified in the documentation.
Set a debugger break-point inside an attribute constructor and write some reflection code that reads those attributes. You'll notice that the attribute objects won't be created until they are returned from the relfection API. Attributes are per class. They are part of the meta data.
Have a look at this:
Program.cs
using System;
using System.Linq;
[My(15)]
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Program started");
var ats =
from a in typeof(Program).GetCustomAttributes(typeof(MyAttribute), true)
let a2 = a as MyAttribute
where a2 != null
select a2;
foreach(var a in ats)
Console.WriteLine(a.Value);
Console.WriteLine("Program ended");
Console.ReadLine();
}
}
MyAttribute.cs
using System;
[AttributeUsage(validOn : AttributeTargets.Class)]
public class MyAttribute : Attribute
{
public MyAttribute(int x)
{
Console.WriteLine("MyAttribute created with {0}.", x);
Value = x;
}
public int Value { get; private set; }
}
Result
Program started
MyAttribute created with 15.
15
Program ended
But don't worry about the performance of attribute constructors. They are the fastest part of reflection :-P
The metadata in the executable or DLL stores:
A metadata token indicating the constructor to call
The arguments
When I get to that section of my CLI implementation, I plan to lazy-call the constructor the first time GetCustomAttributes() is called for the ICustomAttributeProvider. If a particular attribute type is requested, I'll only construct the ones required to return that type.