override metadata in static constructor? - c#

I have a class that inherits the TextBox Class, call it MyTextBox
I'd like to redefine the default Background value for this class.
So I looked for a way to do so and found a good option: call BackgroundProperty.OverrideMetadata()
trouble is: where can I put this?
in the App.OnStartup()? Ugly and not practical, I'd like that to be in my Class's code file.
in the Class's contructor? I get an exception:
PropertyMetadata is already registered
for the type 'MyTextBox'.
(seems fine to me, I understand why I get this perfectly)
So I looked again a found about the static constructor in C# (did not no about that earlier, what a pity)
so here's my code:
public class MyTextBox : TextBox
{
static MyTextBox()
{
MyTextBox.BackgroundProperty.OverrideMetadata(typeof(MyTextBox), new FrameworkPropertyMetadata(App.Current.Resources["CustomBackgroundBrush"]));
}
}
now, I'm pretty happy whith this, but Microsoft isn't. Namely, when I use the code analysis feature, I get this:
CA1810: Initialize reference type static fields inline
Hence my question: what can I do about it?
ignore the warning? >> I don't like to ignore warnings
move the call to the overrideMetadata method? >> I'd like to, but where?
any hints welcome, thanks
Edit: I'll add that I don't fully understand why I get this warning, since I am not initializing anything per say in my static constructor, or am I?

Here is the link from MSDN for overridding metadata for overridding metadata for a dependency property:
It states:
"Overriding metadata on a dependency property must be done prior to that property being placed in use by the property system (this equates to the time that specific instances of objects that register the property are instantiated). Calls to OverrideMetadata must be performed within the static constructors of the type that provides itself as the forType parameter of OverrideMetadata."
And the wording from the link you posted to CA1810 about when to suppress warnings:
When to Suppress Warnings
CA1810
It is safe to suppress a warning from this rule if performance is not a concern; or if global state changes that are caused by static initialization are expensive or must be guaranteed to occur before a static method of the type is called or an instance of the type is created.
So, your current implementation and suppression of the warning is probably the correct route.

Related

Roslyn 2.x CodeFix that implements a missing interface, delegated to a member, VS 2017

BACKGROUND
I am seeking to create a Roslyn CodeFix that will respond to a Diagnostic warning from the built in Analyzer shipped with Visual Studio, that will identify the interface that is not - or is partially - implemented, allowing me to loop through the missing members, and generate custom code that delegates a method call to a Member field of a type that implements the interface.
(The Roslyn Analysers and CodeFixes that ship with Visual Studio do offer this functionality, but I need to customise and extend the generation of code, which is not possible as the Microsoft implementations are all marked as internal.)
Please note: The interface is almost always going to be located in an external, third-party assembly, to which I do not have access to the source.
e.g. starting from:
public class CustomDocumentDBClient : IDocumentClient
{
}
The desired outcome would be similar to the following (in practice I will be creating multiple versions that add additional code to wrap the method calls, once the basic principals are working):
public class CustomDocumentDBClient : IDocumentClient
{
// Field to which calls are delegated, initialised by the constructor
private readonly IDocumentClient _documentClientImplementation;
// Constructor
public CustomDocumentDBClient (IDocumentClient documentClientImplementation)
{
_documentClientImplementation = documentClientImplementation;
}
// Interface method that delegates to private field for invocation
public Task<ResourceResponse<Attachment>> CreateAttachmentAsync(string documentLink, object attachment, RequestOptions options = null)
{
return _documentClientImplementation.CreateAttachmentAsync(documentLink, attachment, options);
}
// Interface method that delegates to private field for invocation
public Task<ResourceResponse<Attachment>> CreateAttachmentAsync(string documentLink, Stream mediaStream, MediaOptions options = null, RequestOptions requestOptions = null)
{
return _documentClientImplementation.CreateAttachmentAsync(documentLink, mediaStream, options, requestOptions);
}
...
other methods
...
}
WHAT I HAVE TRIED
I have spent some time reading tutorials regarding the Syntax Tree and Semantic Model functionality of Roslyn.
I have also examined the Roslyn source code from GitHub - which does include the exact feature that I wish to implement; however, the code is heavily interwoven throughout various complex classes, and is implemented as internal methods, which cannot be overridden or extended, or indeed extracted into a standalone project.
From investigating multiple samples, and also a related SO question How to see if a class has implemented the interface with Roslyn I have concluded that I must use the Roslyn Semantic Model to obtain information about the interface, and it's declared members.
Once I can obtain the interface Members, I am able to build the required output code using the SyntaxFactory, and I have used the 'Roslyn Quoter' for guidance.
Creating a CodeFix from the default template, that responds to the correct Diagnostic codes is straightforward, and this is functioning.
ISSUES
The problem I am having, is taking the token identified by the Diagnostics Location, which appears to be a SimpleBaseTypeSyntax token, and
Verifying that it is actually representing an interface,
Obtaining a Symbol definition that allows me to enumerate the Members of the third-party interface.
The Syntax Visualizer indicates that the interface declaration node is of type SimpleBaseType.
I am therefore using the following code to obtain the token from the Syntax Tree as SimpleBaseTypeSyntax-
// Find the interface Syntax Token detected by the diagnostic.
var interfaceBaseTypeSyntax =
root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf()
.OfType<SimpleBaseTypeSyntax>().First();
a) This does return a token that contains the information of the relevant node in the Syntax Tree - however, I cannot see any 'InterfaceTypeSyntax' type or IsInterface method to validate that it is actually an interface.
b) I believe I should be able to use semanticModel.GetSymbolInfo(interfaceBaseTypeSyntax), however this always returns null - bear in mind the interface is declared in an external assembly.
Is there something I need to do to make that information available through GetSymbolInfo, or is there another approach I should be taking...?
Many thanks for your advice...
It's rather embarrassing to have found this so quickly after posting, but the solution seems to be to refer to the Identifier which is a descendant of the SimpleBaseTypeSyntax.
var interfaceSymbolInfo =
semanticModel.GetSymbolInfo(interfaceBaseTypeSyntax.DescendantNodes().First());
And, by calling:
var interfaceTypeInfo =
semanticModel.GetTypeInfo(interfaceBaseTypeSyntax.DescendantNodes().First());
I can then use interfaceTypeInfo.Type.IsInterface to verify I have indeed found an interface type, and also access interfaceTypeInfo.Type.GetMembers().
The answer was staring me in the face via the Syntax Visualizer.
I'm leaving this open for now, in case others have a better solution... thanks!
In this case, the syntax node you are looking at refers to a type not a symbol. GetSymbolInfo will return null if the node you pass in is not a symbol. You want to use semanticModel.GetTypeInfo(interfaceBaseTypeSyntax).

Properties and auto-implementations

I'm using .NET 4.5 in a VSTO addin for outlook 2013. I'm having some trouble fully grasping properties and accessors. Auto-implemented accessors which I assume are when you just write get; set; rather than get { //code }, etc. are also giving me trouble. I have a dictionary I use internally in my class. Here is my code:
private Dictionary<string, string> clientDict { get; set; }
private Dictionary<string, string> clientHistoryDict { get; set; }
then later on:
clientDict = new Dictionary<string, string>();
clientHistoryDict = new Dictionary<string, string>();
I am using the same names as the properties in the code later on, within the same class.
I never actually write:
private Dictionary<string, string> _clientDict; // etc.
to create the variables I just was using the property directly.
I tried changing my code to do this, and I had some issues and realized my understanding of properties is a bit mixed up.
Here are a few questions I need clarified that I can't seem to find the correct answer to.
First, is there any reason to use a private property? My dictionaries are never accessed outside of the class or in any derived classes so is there a reason to even use properties? I don't use any special validation or anything in the setter or anything like that.
Second, when I tried to change my code to use variables and then access them via the properties like your typical property example would, I ran into problems. I found an example where the getter was set to return _clientDict, but the setter was just set; It gave me the error: that I must give set a body because it's not abstract or partial. Why would it not auto-implement the setter for me in this instance?
Last, when I call new on the properties in the same class that it is declared in, what is the difference between doing that with a property and a normal variable of the same type? Do properties differ at all from variables in that case? Is it bad practice to use properties this way when it should be accomplished with private variables?
These may be some misguided questions but I can't find any other place that has the information to help me understand these distinctions. I've been playing around with properties to try and figure all of this out but I could use so me assistance.
First, is there any reason to use a private property?
Usually, no. Properties are great for encapsulation. One advantage (there are many more) of using a property is that it can do validations before assignment. When you have something private, you usually don't need to protect things from yourself. Also, properties have the advantage of setting different accessors (private, protected, etc), where fields do not.
Why would it not auto-implement the setter for me in this instance?
We have to understand that auto-implemented properties aren't black magic. The compiler will generate a private backing field for us, instead of providing one ourselfs. From his point of view, he sees that you have a getter that returns a private field, but the setter is automatic, thatusually would indicate some kind of logical error in your code. Why would you return one value but set a completely different one? When you create a property with a backing field, you have to provide both the getter and setters, those are the rules.
when I call new on the properties in the same class that it is
declared in, what is the difference between doing that with a property
and a normal variable of the same type?
Semantically, Nothing. new belongs to the type being constructed and will emit a constructor call. The difference is once the newly created object is assigned. A field will cause the compiler to emit a stfld opcode. For a property it'll emit a call to invoke the property setter. When you access a property, the compiler will end up calling get_YourPropertyName vs a ldfld on the field.
Is it bad practice to use properties this way when it should be
accomplished with private variables?
I wouldn't call it bad practice, but I would find it a bit weird to have a private property.
For more insights on fields and properties, see What is the difference between a Field and a Property in C#?
Is there any reason to use a private property?
No - that's the whole point of auto implementation. It saves you having to write all that extra code when all you want to do is get or set what's in the private member variable. .Net handles the creation of the shadowing private member variable behind the scenes.
When I tried to change my code to use variables and then access them via the properties like your typical property example would, I ran into problems. I found an example where the getter was set to return _clientDict, but the setter was just set; It gave me the error: that I must give set a body because it's not abstract or partial. Why would it not auto-implement the setter for me in this instance?
My understanding is that it's all or nothing with auto implementation. (Open to correction there though). That said I have seen code compile with the set block simply defined as set { }. Edit: Just to clarify the set { } block won't actually set the value, it essentially swallows the call and does nothing - it will compile though.
When I call new on the properties in the same class that it is declared in, what is the difference between doing that with a property and a normal variable of the same type? Do properties differ at all from variables in that case? Is it bad practice to use properties this way when it should be accomplished with private variables?
There is no real difference as far as I am aware. The exact same thing is happening, it's just that .Net is handling the plumbing for you.

WM_SETFOCUS, where defined for C#?

I need to find out where WM_SETFOCUS is defined.
For instance, I know it isn't System.Windows.Forms.WM_SETFOCUS
I've looked online, and everything seems to just use the name with no mention of how to let your compiler know the name.
I DO know the integer value it represents, but I really want to reference an authoritative assembly, and not just litter my code with constants.
I am using the value in a class which implements IMessageFilter.
ADDED DETAILS:
Using IMessageFilter,
I am getting messages, and the messages have a Msg field (int) which identifies its type. Where can I find C# definitions of those integer values? (I don't need one named WM_SETFOCUS, I just need something with all the definitions of the values I am receiving.)
Since Microsoft supplies IMessageFilter, shouldn't they also supply the information needed to make it useful?
It would seem to be defined in System.Windows.Forms.NativeMethods.WM_SETFOCUS (Which, unfortunately is an internal class). It's also defined in Microsoft.VisualStudio.NativeMethods.WM_SETFOCUS
If you're worried about littering your code with native methods, I would do as the framework does and create an internal NativeMethods static class, and dump everything interop-related in it. At least you can keep it all in one place.

Why is overriding static method alowed in C#

protected static new void WhyIsThisValidCode()
{
}
Why are you allowed to override static methods?
Nothing but bugs can come from it, it doensn't work as you would think.
Take the following classes.
class BaseLogger
{
protected static string LogName { get { return null; } }
public static void Log(string message) { Logger.Log(message, LogName); }
}
class SpecificLogger : BaseLogger
{
protected static string LogName { get { return "Specific"; } }
}
this is alowed, and the code
SpecificLogger.Log("test");
is altso alowed, but it doesn't do what you would think by looking at the code.
it calls Logger.Log with LogName = null.
So why is this allowed?
The new keyword does not override a method. It instead creates a new method of the same name which is independent of the original. It is not possible to override a static method because they are not virtual
You're not overriding it, you're hiding it. A normal method would exhibit exactly the same behavior so there is nothing specific to static methods here.
Hiding is only useful in a few cases. The one where I came across most often is making the return type more specific in a derived class. But I never had that occur with static methods.
One area where static functions with a certain name might be useful is if you use reflection and want to get information on each class by returning it from a method. But of course in most cases an attribute fits better.
And it's not likely to create bugs since your code produces a compiler-warning:
Warning 'StaticHiding.SpecificLogger.LogName' hides inherited member 'StaticHiding.BaseLogger.LogName'. Use the new keyword if hiding was intended.
And if you use new you should know what you're doing.
Others have pointed out that this isn't overriding, but that still leaves your original question: why are you able to do it? (But the question is really "why can you hide static methods".)
It's an inevitable feature of supporting the independent versioning of component that contain base classes and components that use those base classes.
For example, imagine that component CompB contains the base class, and some other component CompD contains a derived class. In version 1 of CompB, there might not have been any property called LogName. The author of CompD decides to add a static property called LogName.
The critical thing to understand at this point is that the author of v1 of CompD was not intending to replace or hide any feature of the base class - there was no member called LogName in the base class when they wrote that code.
Now imagine that a new version of the CompB library is released. In this new version, the author added a LogName property. What's supposed to happen in CompD? The options appear to be:
CompD no longer works because the LogName it introduces clashes with the LogName added to CompB
Somehow make the CompD's LogName replace the base CompB LogName. (It's not actually remotely clear how this could work with statics. You could envisage this with non-statics though.)
Treat the two LogName members as being completely different members that happen to have the same name. (In reality, they don't - they're called BaseLogger.LogName and SpecificLogger.LogName. But since in C# we don't always need to qualify the member name with the class, it looks like they're the same name.)
.NET chooses to do 3. (And it does that with both statics and non-statics. If you want behaviour 2 - replacement - with non-statics, then the base has to be virtual and the derived class has to mark the method as override to make it clear that they were deliberately overriding a method in the base class. C# will never make a derived class's method replace a base class's method unless the derived class explicitly stated that this is what they wanted.) This is likely to be safe because the two members are unrelated - the base LogName didn't even exist at the point where the derived one was introduced. And this is preferable to simply breaking because the latest version of the base class introduced a new member.
Without this feature, it would be impossible for new versions of the .NET Framework to add new members to existing base classes without that being a breaking change.
You say that the behaviour isn't what you expect. Actually it's exactly what I'd expect, and what you'd probably want in practice. The BaseLogger has no idea that the SpecificLogger has introduced its own LogName property. (There's no mechanism by which it could because you cannot override static methods.) And when the author of SpecificLogger wrote that LogName property, remember that they were writing against v1 of BaseLogger which didn't have a LogName, so they weren't intending that it should replace the base method either. Since neither class wants replacement, clearly replacement would be the wrong thing.
The only scenario in which you should ever end up in this situation is because the two classes are in different components. (Obviously you can contrive a scenario when they're in the same component, but why would you ever do that? If you own both pieces of code and release them in a single component, it'd be mad ever to do this.) And so BaseLogger should get its own LogName property, which is exactly what happens. You may have written:
SpecificLogger.Log("test");
but the C# compiler sees that SpecificLogger doesn't provide a Log method, so it turns this into:
BaseLogger.Log("test");
because that's where the Log method is defined.
So whenever you define a method in a derived class that isn't attempting to override an existing method, the C# compiler indicates this in the metadata. (There's a "newslot" setting in the method metadata that says, this method is meant to be brand new, unrelated to anything in the base class.)
But this gives you a problem if you want to recompile CompD. Let's say you've got a bug report due to some entirely unrelated bit of code and you need to release a new version of CompD. You compile it against the new verison of CompB. If the code you've written wasn't allowed, you wouldn't actually be able to - old code that's already compiled would work, but you wouldn't be able to compile new versions of that code, which would be a bit mad.
And so, to support this (frankly somewhat obscure) scenario, they allow you to do this. They generate a warning to let you know that you've got a naming clash here. You need to supply the new keyword to get rid of it.
This is an obscure scenario, but if you want to support inheritance across component boundaries, you need this, otherwise the addition of new public or protected members on a base class would invariably be a breaking change. That's why this is here. But it's bad practice ever to rely on it, hence the fact that you get a compiler warning. The use of the new keyword to get rid of the warning should only ever be a stopgap.
The bottom line is this: this feature exists for one reason only, and that's to get you out of a hole in situations where a new version of some base class has added a member that didn't previously exist, and which clashes with a member that's already on your derived class. If that's not the situation you're in, don't use this feature.
(I think they should actually issue an error rather than a warning when you leave out new, to make this more clear.)
Static methods and fields do not belong to class instances but to class definitions. Static methods do not play part in the virtual dispatching mechanism and are not part of the virtual method table.
They are just methods and fields on that specific class.
It may look like the methods and fields are "inherited" because you can do SpecificLogger.Log(), but that is just something to keep you from having to refer to the base class all the time.
Static methods and fields really are just global methods and fields, just the OO kind.
for my surprise following code is allowed and compiles without any error on .net Framework 4.5.1, VS 2013.
class A
{
public static void Foo()
{
}
}
class B : A
{
}
class Program
{
static void main(string[] args)
{
B.Foo();
}
}
You aren't overriding the property in the base class, but instead hiding it. The actual property used at runtime depends on what interface you're working against. The following example illustrates:
SpecificLogger a = new SpecificLogger();
BaseLogger b = new SpecificLogger();
Console.Write(a.Log); // Specific
Console.Write(b.Log); // null
In your code the Log method is actually working against the BaseLogger interface - because the Log method is part of the BaseLogger class.
Static methods and properties can not be overridden, and when you want to hide a property you should use the new keyword to denote that you're hiding something.

Why does resharper suggest readonly fields

Why is ReSharper suggesting readonly field for 'settings' in my example below?
If I understand correctly, you should use readonly modifier if you change this field only in constructor, but in my example I also change it in another method in the same class.
What am I missing?
public partial class OptionsForm : Form
{
private Settings settings;
public OptionsForm(Settings s)
{
settings = s;
}
private void SaveData()
{
settings.ProjectName = TextBoxProject.Text;
}
}
When a reference type is declared as readonly, the pointer is immutable, but not the object it points to. This means that:
a reference type data member can be initialized in order to point to an
instance of a class, but once this is done it's not possible to make it
point to another instance of a class outside of constructors
the readonly modifier has no effect on the object the readonly data member
points to.
Read a detailed article on this
Mark a C# class data member as readonly when it’s read only
Remember the primary reason for coding standards and design patterns is to make to easier for people to understand your code.
By marking a field as “readonly” you
are telling the reader of the class
that they don’t need to consider how
the value of the field is changed.
However as the object the readonly field points to can have it’s state change, marking a field as readonly can be misleading at times. So think about weather it helps the reader (e.g a person) of your code understand your design or not.
If the values in the object that the field points to changes within the object lifetime, then I don’t think a field should be marked read-only. (E.g the object pointed to should be behave as if it is immutable by the time the contractor on your class is called)
(However there are some exceptions, e.g it is OK to use a read-only field to point to a logger even thought the logger does change the state of the log file.)
ReSharper suggests making "settings" readonly:
readonly private Settings settings;
public OptionsForm(Settings s)
{
settings = s;
}
because, upon scanning your code it concludes that your "settings" field only occurs in the constructor for this same class.
If howerver you were to provide a partial class or some other code in this class that modified "settings", it would no longer suggest it was readonly.
Once marked readonly the compiler will flag as warnings various misuses of the field, such as:
The left-hand side of an assignment must be an l-value
which is the same error you get when you attempt to assign a value to a constant.
also the use of ref and out parameter modifiers are limited.
By following ReSharpers suggestion you will be warned by the compiler if you attempt to misuse a field that you really intend not to change after initialization.
You aren't changing settings outside of the constructor, the object is the same one in SaveData. The object properties might be changing but not the object reference, so it seems to make sense from a Resharper perspective.
The SaveData() method does not change the settings variable, it changes one its properties. The contents of settings (what it refers to) is only set in the constructor.
Actually, you're right and Resharper is wrong. A field should only be marked readonly if it is immutable in its entirety. In your example if you make it readonly and enable Microsoft's Code Analysis it will warn you that Settings has mutable properties.
This seems to be a bit strange, I can't imagine that Eric Lippert et al, didn't consider the obvious fact that making a reference immutable doesn't make instance pointed to by the reference immutable, though the mentioned Code Analysis rule does support the view of those above (http://msdn.microsoft.com/en-us/library/ms182302(v=VS.100).aspx).
It still doesn't really make any sense. If mutable instances should not be readonly, then, in my view, it should be a compile-time error, seems rather pointless otherwise.
I can see the use of making a reference immutable, rather than the instance it points to.

Categories