If you define the following class:
public class Test
{
public string Something { get; set; }
public string AnotherThing { get; set; }
public string DefaultStringValue { get; set; }
}
then, when you list the properties with IntelliSense, DefaultStringValue appears first in the list, despite this not being in alphabetical order:
If you change the property name to anything else, normal service is resumed:
Anyone know why this is? I'm curious...
(Note: I'm also using Resharper Ultimate 2018.1.2)
This is IntelliSense (and/or ReSharper) being, well, intelli-gent, and trying to help you re-use things you've used previously. If you start again from nothing, you'll find that things are alphabetical:
I'm betting that at some point in the past, you've made use of the DefaultStringValue property, and not the others, so it's suggesting it first:
Having renamed it, if you enter the line t.DefaultStringValu = "x";, then delete it again, next time you enter t. and invoke IntelliSense, DefaultStringValu will now be top of the list:
Related
Interfaces are no types, so when implementing them, their property attributes are not inherited. (which would be true of a base-class)
So, I'm currently wrapping my head around how to make this happen. Following example should pretty much explain what I mean, but unfortunately is not working as expected.
Reason is obvisously to centralize Instructions / Attributes without having to copy / paste them over and over.
public interface IPermissionBasedControl
{
[Browsable(true), Category("PermissionSystem"), Description("AccessKey required in order to use this control.")]
String PermissionKey { get; set; }
}
public class ExtendedTextBox : TextBox, IReadOnlyControl, IDataBindable, IPermissionBasedControl
{
...
[AttributeProvider(typeof(IPermissionBasedControl))]
public string PermissionKey { get; set; }
...
}
Expectation: Visual Studio Designer will pick the Category, Browsable and Description Attribute from IPermissionBasedControl and display the property PermissionKey accordingly in the Designers Property-Window, when working with a ExtendedTextBox.
Actual result: Nothing happens, Default Category Misc is applied, no Description, Browsable default yes is applied.
Is it not working, because Visual Studio Designer does not respect the AttributProvider-Attribute?
Is it not working, because AttributeProvider cannot target an Interface?
I've also tried method access to no success:
public class ExtendedTextBox : TextBox, IReadOnlyControl, IDataBindable, IPermissionBasedControl
{
...
[AttributeProvider(nameof(IPermissionBasedControl), nameof(IPermissionBasedControl.PermissionKey))]
public string PermissionKey { get; set; }
...
}
Okay, It seems like I had a wrong interpretation about what AttributeProvider is doing:
AttributeProviders description is Enables Attribute Redirection - but this doesn't mean, that it will (in my example) attach the Attributes of IPermissionBasedControl.PermissionKey to ExtendedTextBox.PermissionKey, the AttributeProvider is having effect on the Attributes of the type of the property.
i.e.: If I would specify
[AttributeProvider(typeof(Color))]
public object PermissionKey { get; set; }
the VisualStudio Designer would now Apply the Attributes of Color to the Value-Field for picking the object. (And therefore show a color-picker)
So, technically spoken, the AttributeProvider redirects Attributes for the type of the property, not for the property itself.
I have written an attribute class which I later used for sorting properties.
[AttributeUsage(AttributeTargets.Property)]
class OrderAttribute : Attribute
{
internal OrderAttribute(int order)
{
Order = order;
}
public int Order { get; private set; }
}
I want this to be unique for class properties, e.g.
Valid scenario
[Order(1)]
public string Tier3 { get; set; }
[Order(2)]
public string Tier4 { get; set; }
Invalid Scenario since value "1" is repeated.
[Order(1)]
public string Tier3 { get; set; }
[Order(1)]
public string Tier4 { get; set; }
PS: Attribute values can be repeated for different class properties but not in same. How can I achieve this?
Although attribute values can be repeated, there's no easy way supported to make sure they are unique (they are run time only), you would need to check when actually sorting as Johnathan has already mentioned. There are ways around this, but is it worth it in the long run? A few options I can think of are:
Hook into the actual build process, create a build task that uses reflection to check and fail if needed.
Run a post-build (post build event) step that loads your dll and reflects on those attribute types.
Create a possible rule that will check for uniqueness.
There may be other ways, but these are the one's I could think of at the moment.
I have an entity that needed a list of type int. Due to this being an internal tool that only I would use, I didn't want to spend a lot of time making a UI/view to edit the list and I sort of cheated.
So, I have the following class:
myitem.cs
public int ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
virtual public ICollection<Size> Sizes {get;set;}
size.cs
public int ID { get; set; }
public int Size { get; set; }
Between the controller and view controller, I did some funky bits. I had a single text field in the view controller called "Sizes" and I then split the input on a comma to an array, and assign the list to Sizes.
This works perfectly and as expected.
string[] sizes = model.sizes.Split(',');
myitem.size = new List<sizes>();
foreach (string item in sizes)
{
myitem.size.Add( new sizes {Size=int.Parse(item)});
}
In the edit one, I find the object, and create a new text string that basically gets all of them and this also works.
In the edit saving controller, no matter what I try, it seems to append. So, I basically did the following:
MyItem myitem = db.myitems.find(id);
...auto mapper stuff from viewmodel to model...
myitem.sizes=null;
...call same bits as create to split and add to sizes...
db.savechanges();
However, I am now finding that whatever I try to do in edit, it simply adds to the list in addition to what is already there - I can't seem to find a way to remove it.
I have tried many different things (instead of = null, foreach and remove(), and a few others) without much luck.
In the end, I don't think this is the best approach at all as I am going to end up dropping the items and recreating them by the thousands for the sake of saving a few minutes, so, I am going to create a DBSet for sizes and do an ajax interface to list/delete/add them separate to the main model. (If there is an easy way, please let me know?!)
However, the fact that this didn't work has annoyed me and I was wondering if anyone knows why?
We consume a WCF service using C# code. The client was generated in Visual Studio by right-clicking "Add Service Reference" and pointing it at the WSDL.
Recently, the WCF provider adding some properties to one of the objects they serialize. The class went from
public class MyClass
{
public string Foo { get; set; }
public string Baz { get; set; }
public string Zed {get; set; }
}
to this:
public class MyClass
{
public string Foo { get; set; }
public string Bar { get; set; } //<= New Property
public string Baz { get; set; }
public string Zed {get; set; }
}
On our end, this caused Baz and Zed to suddenly start being null when deserialized, until we updated the service reference. In fact, the real object had some ~20 properties alphabetically after Bar, and they were all null (or 0 for ints, false for bools, etc).
It seems an odd way for the deserialization to fail. It didn't throw an exception or ignore the new properties it didn't know anything about.... it just made every property that appeared alphabetically after the new one deserialize to the default value.
So my question is, what's going on here and how do I prevent it? Preferably, I'd like some kind of setting for the client to tell it to "ignore new properties," but telling the service provider how they can prevent future breaking changes would be fine too.
MSDN has an article which lists the serialization ordering of the datamembers. One key point from that document:
current type’s data members that do not have the Order property of the
DataMemberAttribute attribute set, in alphabetical order.
So if you add a new property, without the Order-property of the DataMemberAttribute, the property is alphabetically ordered.
Based on discussion here, your only options are:
Change the serializer to something else
Make sure that the order of the elements in XML matches the order of your properties. Maybe you can always use the Order-property of the DataMemberAttribute?
Make sure that your dll's line up, I've seen some pretty funky issues in the past where one side of a service was pointing to an outdated dll
also remember the fundamentals of data contracts
I'm currently working on some existing C# code and i simply want to set a property to null when a given code doesn't exist in the system.
The code i currently have looks like this:
if (!CodeExists(SomeClass.Code))
{
SomeClass.Code = null;
}
So assume that SomeClass.Code starts with a value of 100. It then checks if that Code exists with the method CodeExists(). If it can't find the code it should set SomeClass.Code = null.
But when i step through this piece of code with the debugger then i see that SomeClass.Code doesn't change at all, eventhough the debugger comes inside the if statement.
When i look at the property Code i see that it is declared as virtual:
public virtual CodeNumber Code { get; set; }
Does that mean i cannot simply change the value when it is declared as virtual? Is there anything i can do to change that value of Code?
Seems some other part of the code is the problem:
public SomeClassProjection SomeClass
{
get
{
// some stuff is done here
SomeClassState.Value = queryProcessor
.Execute(new ExistingProductsQuery { OrderNumber = SelectedOrderNumber });
return SomeClassState.Value;
}
}
So SomeClassState is returned. And that is defined like this:
public ViewValue<SomeClassProjection> SomeClassState;
So it does use another class like some of you suggested. And ViewValue clearly tells it is readyonly. That means i have to take another approach, but at least i now know what actually is prevents me from editting that property and that virtual has nothing to do with it.
About this topic:
So how do i accept an answer now that i found the solution? Or do i need to close this topic?
Seems some other part of the code is the problem:
public SomeClassProjection SomeClass
{
get
{
// some stuff is done here
SomeClassState.Value = queryProcessor
.Execute(new ExistingProductsQuery { OrderNumber = SelectedOrderNumber });
return SomeClassState.Value;
}
}
So SomeClassState is returned. And that is defined like this:
public ViewValue<SomeClassProjection> SomeClassState;
So it does use another class like some of you suggested. And ViewValue clearly tells it is readyonly. That means i have to take another approach, but at least i now know what actually is prevents me from editting that property and that virtual has nothing to do with it.