I have many Model-Classes which implement the INotifyPropertyChanged-Interface in order to update the UI when value changed.
Sadly the properties must be written fully to support this feature. I decreased my code already by using the 'SetPropertyValue'-Method() in BaseClass.
private string _title;
public string Title
{
get { return title; }
set { SetPropertyValue("Title", ref _title, value ); }
}
But with 20 properties written like that in one file it is not so simple to understand the content of the file in a short time unlike to the auto implemented properties.
What I want is to write my Property like this:
[NotifyChanged]
public string Title { get; set; }
I checked already PostSharp but in the free version there are only 10 classes included (it's a hobby project so I don't want to pay much money).
Is there any possibility to attach my one logic to C#-Compiler (as a pre-compiler)?
Such a feature I would like to use on different places in my code to reduce unneccessary coding lines (especially for auto-properties).
Or maybee a VisulStudio-Extension?
Try Fody. It is library which modifies IL code during build process using dedicated msbuild task.
It has large base of addins including PropertyChanged which should suit in your scenario.
This addin gives you attribute ImplementPropertyChanged which you can apply to a class. Then Fody will generate code implementing INotifyPropertyChanged to all auto-properties.
Second option if you have ReSharper version 7 or higher. It has refactoring which can help you with implementation of INotifyPropertyChanges. For example it can transform auto-property to "normal" property implementing the interface.
Thou it may not fully satisfy you - this approach may be interesting for you because it does not involve additional libraries and assembly modification.
Another option is Castle DynamicProxy. The difference between PostSharp and Fody is that DynamicProxy generates its proxies on the fly at runtime.
Related
I am creating an automation tool for inserting properties to existing class's source code. E.g. I have an existing source code like this:
public class MyClass
{
//class members goes here
}
I want to modify it to become like this
public class MyClass
{
//class members goes here
public string MyProp { get; set; }
}
and save it to the same file.
The class name, property type and property name will be known before hand and can be considered parameters of the operation. Any idea how to do this easily? Perhaps regex replace will work for this, but I don't know which expression to use that will be flexible regardless of the source code's new line, whitespace and identation policy.
EDIT: What I'm looking for is simply automatically generating the source code, not manipulating classes during runtime
A clean way of doing this, is by using T4 templates to generate partial classes.
T4 templates are a good way to generate code at compile time.
These generated files should not be modified by the developer, instead the developer creates another file with additional definitions of members of the partial class.
That way you can tweak and run the generator again and again without messing with the custom code.
The following approach using regular expressions should work, although I don't think this could be the best way of doing what you need. Don't really know, that depends on your needs. I do it all the time (either creating scripts that modify the .cs files, or macros from Notepad++). Perhaps you might also want to take a look at partial classes.
string text =
#"namespace X {
public class MyClass {
//Text here
}
}";
string className = "MyClass";
string propertyType = "string";
string propertyName = "MyProperty";
string regex = string.Format(#"( *)((public?)\s*(static)?\s*class\s+{0}\s*{{)", className);
string replacement = string.Format("$1$2\r\n\r\n$1 public {0} {1} {{ get; set; }}", propertyType, propertyName);
var modified = Regex.Replace(text, regex, replacement);
Console.WriteLine(modified);
The above code will print:
namespace X {
public class MyClass {
public string MyProperty { get; set; }
//Text here
}
}
Edit: As you can see, it indents the code correctly. It uses the same number of spaces of the line that contains the class definition + 4 more. If you want to add a tab, or whatever, you can change the regex.
For Adding At RunTime
Assembly can not be changed at run time so either you need to generate a you DLL at runtime and load it or you can use ExpandoObject as described in this SO question
For Adding At Compile Time
if you do not want to add code at runtime than you are exactly looking For CodeDom
For Adding Between Runtime and Compile time
Just wanted to throw in another option. Although in soooo many ways you don't want to do it, at least from what little information you gave.
You can use IL weaving. This option happens AFTER compile (to MSIL) but BEFORE runtime. The effects are that your class gets all the benefits of compile time manipulation, but gives you much more information than CodeDom could.
Implementations of MSIL weaving include PostSharp.Net(Commercial product) and Mono.Cecil (N.B. Don't let the Mono part fool you, it works on .Net as well).
Advantages include:
Its (runtime) as fast as a compile time method
You have a lot of information that CodeDom loses (partial classes are an especially painful problem in CodeDom)
Disadvantages include:
Weaving is hard (you even lose compile time checking)
There is very little IDE support for weaving
You might try cog, a general purpose code generator written in Ruby. cog has an embeds feature which would suit your purpose well. To achieve your goal you would modify your class like this
public class MyClass
{
// class members goes here
// cog: auto-properties
}
then write a cog generator (a short ruby script) like this
embed 'auto-properties' do |c|
" /* whatever you return gets injected into #{c.filename} */"
end
In the example, c is an instance of EmbedContext. Once you've setup a generator you run it with a command-line invocation
$ cog gen
Updated src/MyClass.cs - 1st occurrence of embed 'auto-properties'
and now your class looks like this
public class MyClass
{
// class members goes here
// cog: auto-properties {
/* whatever you return gets injected into MyClass.cs */
// cog: }
}
It's up to you how to generate the properties given the filename. cog is pretty flexible and also supports using ERB templates to generate code.
We're often told we should protect encapsulation by making getter and setter methods (properties in C#) for class fields, instead of exposing the fields to the outside world.
But there are many times when a field is just there to hold a value and doesn't require any computation to get or set. For these we would all do this number:
public class Book
{
private string _title;
public string Title
{
get => _title;
set => _title = value;
}
}
Well, I have a confession, I couldn't bear writing all that (really, it wasn't having to write it, it was having to look at it), so I went rogue and used public fields.
Then along comes C# 3.0 and I see they added automatic properties:
public class Book
{
public string Title { get; set; }
}
Which is tidier, and I'm thankful for it, but really, what's so different than just making a public field?
public class Book
{
public string Title;
}
In a related question I had some time ago, there was a link to a posting on Jeff's blog, explaining some differences.
Properties vs. Public Variables
Reflection works differently on variables vs. properties, so if you rely on reflection, it's easier to use all properties.
You can't databind against a variable.
Changing a variable to a property is a breaking change. For example:
TryGetTitle(out book.Title); // requires a variable
Ignoring the API issues, the thing I find most valuable about using a property is debugging.
The CLR debugger does not support data break points (most native debuggers do). Hence it's not possible to set a break point on the read or write of a particular field on a class. This is very limiting in certain debugging scenarios.
Because properties are implemented as very thin methods, it is possible to set breakpoints on the read and write of their values. This gives them a big leg up over fields.
Changing from a field to a property breaks the contract (e.g. requires all referencing code to be recompiled). So when you have an interaction point with other classes - any public (and generally protected) member, you want to plan for future growth. Do so by always using properties.
It's nothing to make it an auto-property today, and 3 months down the line realize you want to make it lazy-loaded, and put a null check in the getter. If you had used a field, this is a recompile change at best and impossible at worst, depending on who & what else relies on your assemblies.
Just because no one mentioned it: You can't define fields on Interfaces. So, if you have to implement a specific interface which defines properties, auto-properties sometimes are a really nice feature.
A huge difference that is often overlooked and is not mentioned in any other answer: overriding. You can declare properties virtual and override them whereas you cannot do the same for public member fields.
It's all about versioning and API stability. There is no difference, in version 1 - but later, if you decide you need to make this a property with some type of error checking in version 2, you don't have to change your API- no code changes, anywhere, other than the definition of the property.
Another advantage of auto-implemented properties over public fields is that you can make set accessors private or protected, providing the class of objects where it was defined better control than that of public fields.
There is nothing wrong in making a field public. But remember creating getter/setter with private fields is no encapsulation. IMO, If you do not care about other features of a Property, you might as well make it public.
Trivial properties like these make me sad. They are the worst kind of cargo culting and the hatred for public fields in C# needs to stop. The biggest argument against public fields is future-proofing: If you later decide you need to add extra logic to the getter and setter, then you will have to do a huge refactor in any other code that uses the field. This is certainly true in other languages like C++ and Java where the semantics for calling a getter and setter method are very different from those for setting and getting a field. However, in C#, the semantics for accessing a property are exactly the same as those for accessing a field, so 99% of your code should be completely unaffected by this.
The one example I have seen of changing a field into a property actually being a breaking change at the source level is something like:
TryGetTitle(out book.Title); // requires a variable
To this I have to ask, why TF are you passing some other class's field as a reference? Depending on that not being a property seems like the real coding failure here. Assuming that you can directly write to data in another class that you know nothing about is bad practice. Make your own local variable and set book.Title from that. Any code that does something like this deserves to break.
Other arguments I have seen against it:
Changing a field to a property breaks binary compatibility and requires any code that uses it to be recompiled: This is a concern iff you are writing code for distribution as a closed-source library. In that case, yes, make sure none of your user-facing classes have public fields and use trivial properties as needed. If however you are like 99% of C# developers and writing code purely for internal consumption within your project, then why is recompilation a big concern? Just about any other change you make is going to require recompilation too, and so what if it does? Last I checked, it is no longer 1995, we have fast computers with fast compilers and incremental linkers, even larger recompilations shouldn't need more than a few minutes, and it has been quite some time since I have been able to use "my code's compiling" as an excuse for swordfighting through the office.
You can't databind against a variable: Great, when you need to do that, make it into a property.
Properties have features that make them better for debugging like reflection and setting breakpoints: Great, one you need to use one of those things, make it into a property. When you're done debugging and ready to release, if you don't still need those functionalities, change it back into a field.
Properties allow you to override behavior in derived classes: Great, if you are making a base class where you think such a scenario is likely, then make the appropriate members into properties. If you're not sure, leave it as a field and you can change it later. Yes, that will probably require some recompilation, but again, so what?
So in summary, yes there are some legitimate uses for trivial properties, but unless you are making a closed source library for public release, fields are easy enough to convert into properties when needed, and an irrational fear of public fields is just some object oriented dogma that we would do well to rid ourselves of.
For me, the absolute deal breaker for not using public fields was the lack of IntelliSense, showing the references:
Which is not available for fields.
If you decide later to check that the title is unique, by comparing to a collection or a database, you can do that in the property without changing any code that depends on it.
If you go with just a public attribute then you will have less flexibility.
The extra flexibility without breaking the contract is what is most important to me about using properties, and, until I actually need the flexibility, auto-generation makes the most sense.
One thing you can do with Fields but not with Properties (or didn't used to be able to ... I'll come to that in a moment) is that Fields can be designated as readonly whereas Properties cannot. So Fields give you a clear way of indicating your intention that a variable is there to be set (from within the constructor) at object-instantiation time only and should not be changed thereafter. Yes, you can set a Property to have a private setter, but that just says "this is not to be changed from outside the class", which is not the same as "this is not to be changed after instantiation" - you can still change it post-instantiation from within the class. And yes you can set the backing field of your property to be readonly, but that moves post-instantiation attempts to change it to being run-time errors rather than compile-time errors. So readonly Fields did something useful which Properties cannot.
However, that changes with C# 9, whereby we get this helpful syntax for Properties:
public string Height { get; init; }
which says "this can get used from outside of the class but it may only be set when the object is initialized", whereupon the readonly advantage of Fields disappears.
One thing I find very useful as well as all the code and testing reasons is that if it is a property vs a field is that the Visual Studio IDE shows you the references for a property but not a field.
My pov after did some researches
Validation.
Allow overriding the accessor to change the behaviour of a property.
Debugging purpose. We'll be able to know when and what the property change by setting a breakpoint in the accessor.
We can have a field set-only. For instance, public set() and private get(). This is not possible with the public field.
It really gives us more possibility and extensibility.
When one choose Refactoring, Encapsulate Fields for let's say:
int m_member;
VS will generate
public int Member
{
get { return m_member; }
set { m_member = value; }
}
For some reason (using a reverse engineerint tool for example which doesn't know this style), I'd like to get the oldish and more verbose style:
public int getMember() {
return m_member;
}
public void setMember(int value) {
m_member = value;
}
Is it possible to configure VS to do so ? Otherwise any other mean with sample code like creating snippet template or even Plugin if necessary ?
Although I don't necessarily recommend this, all refactorings are simply snippets that you can edit. A default installation will put the C# templates in this folder, C:\Program Files\Microsoft Visual Studio 10.0\VC#\Snippets\1033\Refactoring, simply find the one that you want and modify as you see fit.
NOTE: Be sure to take a backup first!!
I'll also agree with everyone else, that this is a REALLY bad idea!
So... you want to write Java/C++/(any language that doesn't support properties) in C#? Why?
Properties are nice because:
Syntax is cleaner.
Debugging is easier (you can see the value in the debugger as if the property were a field).
It is idiomatic. C# developers will furrow their brow at you when they look at your code. Yes, this does sometimes matter, and it certainly matters if you are not the sole developer working on this project.
Even your method naming convention looks like Java. It is a good idea to get into the habit of adopting the idioms of a new language as you learn it.
This pattern is not idiomatic of C# code - and Visual Studio doesn't support it. I would recommend avoiding it in favor of the property syntax. However, if you really do need it for some reason, you can get there with ReSharper. Here's what you do in ReSharper:
Refactor >> Encapsulate Field (this creates a property)
Refactor >> Convert >> Property To Method(s) (this generates the get/set methods)
The first step let's you create a property that wraps the public field.
The second replaces that property with get/set methods whose names you can specify.
is there some way to autogenerate the obvious 2-param constructor for this class in visual studio?
class Thing {
public readonly string a;
public readonly Object b;
}
I guess you're supposed to use the:
new Thing { a = ..., b = ... }
syntax in such cases, but that won't work with readonly fields as above. Another plus of having a constructor is that you can't forget a field.
There is, Resharper supports this functionality. You choose the "generate constructor", pick the fields you want included and you've got your constructor.
Sorry for a post that's not helpful at all, but I just couldn't resist.
I'm afraid that by using things like T4 templates, you'll (probably) lose IntelliSense, which may not be a price you wanted to pay. You could probably write a VS.NET macro to auto-generate code of the constructor (I believe the code model should give you enough information to do that).
Now, here is the useless part of the post - perhaps you could try another .NET language if you're annoyed with the unnecesary verbosity of C#. In F#, you can write implicit constructors and their parameters automatically become (readonly) fields:
type Thing(a:string, b:Object) =
// members can use 'a' and 'b' directly - here is one example:
member this.GetInfo() =
"Some info: " + a + (b.ToString())
In a real-world scenario, you probably wouldn't need to specify the types, because F# could infer them automatically based on the later usage. Experimenting with F# isn't as difficult if you're already familiar with .NET libraries.
You may want to look at T4 templates. It would be fairly simple to write a template which iterates a list of the readonly property names and types and creates the necessary code for the properties and constructor.
T4 templates are built into Visual Studio. Check out Scott Hanselman's blog about T4 templates for more detail.
There are other products which can automate this kind of refactoring. Resharper is one of these, but it is not free.
I've thought of this before and it came to mind again when reading this question.
Are there any plans for "extension properties" in a future version of C#?
It seems to me they might be pretty stright-forward to implement with a little more "compiler magic". For example, using get_ and set_ prefixes on extension method names would turn that method into an extension property:
public class Foo
{
public string Text { get; set; }
}
public static class FooExtensions
{
public static string get_Name(this Foo foo)
{
return foo.Text;
}
public static void set_Name(this Foo foo, string value)
{
foo.Text = value;
}
}
Are there any technical restrictions which would prevent this? Would this create too much stuff going on behind the scenes? Not important enough to be worth the effort?
The official site for feature requests is http://connect.microsoft.com/VisualStudio.
There has already been a request for extension properties here.
Microsoft's answer on 7/29/2008 included the following:
Extension properties are a common
request, and we actually got quite far
with a design for the next version of
the language, but ultimately had to
scrap it because of various
difficulties. It is still on our
radar.
Generally I think this would encourage poor practice.
Properties are supposed to represent some kind of state about the object in question, whereas methods should represent units of work. But many developers tend to put computationally intensive or relatively long-running code in the getters and setters where they would be much more appropriate as methods.
Extending an object is not the same as deriving from it. If you need to add properties, from a philosophical perspective you're talking about needing to add stateful information to the object. That should be done by deriving from the class.
Although I don't think what you're proposing is a good idea, you can get pretty much the same thing with the upcoming dynamic type in C# 4. Part of what is planned is to allow new properties and methods to be added at runtime to existing objects and types. One difference is that you won't have the compile-time checking of an extension property.
There might be something to be said about that kind of trick.
Just look at Attached properties in WPF. They do give tremendous power for declarative behavior attachment. But I'm not sure what that would look like outside of a declarative context...
I'm not sure how that would work. Extensions have to be static, so the property itself would have to static. The means whatever you use to back these properties would also be static. But expect your planned use for these expects them to be associated with the instances indicated by the this keyword rather than the type itself.
"Extension properties" are available today via inheritance. Adding such a beast would encourage poor oop practices and generaly be more trouble than its worth.