The DebuggerDisplay attribute allows to show a custom "value" or interpretation for entire class. This is good, but is there a possibility to force also displaying a standard type member (ie. UInt32) to a hexadecimal value?
There are 2 reasons I want this
some of my members has meaning in hex only (addresses, bit masks)
the hex formatting is global in C# IDE so I have to toggle manually quite often
[DebuggerDisplay("{_value,h}")]
public abstract class DataField
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private UInt32 _value;
// display this member in debugger permanent as HEX
public UInt32 ConstMask { get; set; }
}
One option I see is to declare ConstMask as a class and apply DebuggerDisplay formatting as well, but this will affect my performances and I guess is not a good option to do that just for debug purposes.
Thanks in advance for hints,
When you need more control/code to format your debugger display, you can use nq and the name of a property used to return the string. Like this:
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public abstract class DataField
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private UInt32 _value;
// display this member in debugger permanent as HEX
public UInt32 ConstMask { get; set; }
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private string DebuggerDisplay =>
$"{this.GetType().Name} 0x{this._value:X8}";
}
You are looking for the DebuggerTypeProxyAttribute. This attribute allows you to define a type which can be expanded to show all of the properties.
[DebuggerTypeProxy(typeof(HashtableDebugView))]
class MyHashtable : Hashtable
{
private const string TestString = "This should not appear in the debug window.";
internal class HashtableDebugView
{
private Hashtable hashtable;
public const string TestString = "This should appear in the debug window.";
public HashtableDebugView(Hashtable hashtable)
{
this.hashtable = hashtable;
}
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
public KeyValuePairs[] Keys
{
get
{
KeyValuePairs[] keys = new KeyValuePairs[hashtable.Count];
int i = 0;
foreach(object key in hashtable.Keys)
{
keys[i] = new KeyValuePairs(hashtable, key, hashtable[key]);
i++;
}
return keys;
}
}
}
}
Related
I have a legacy project where I can often see model classes that have up to 100 properties and while debugging I'd like to see them in a particular order as it's an ordered sequence of data. Is there any sort of an attribute that can make Visual Studio debugger to display them in a particular order instead of sorting them by names?
You can use DebuggerDisplayAttribute class to customise debugger description. Please read about it in MSDN.
If you append that attribute to certain class you can define how you want to see description during debugging.
One example from MSDN. Here value and key are will be more visible during debugging:
[DebuggerDisplay("{value}", Name = "{key}")]
internal class KeyValuePairs
{
private IDictionary dictionary;
private object key;
private object value;
public KeyValuePairs(IDictionary dictionary, object key, object value)
{
this.value = value;
this.key = key;
this.dictionary = dictionary;
}
}
Here will be easier to see value and key during debugging.
You can consider DebuggerBrowsableAttribute which determine what will debugger display certain members. You can even hide some members.
Here is some example of DebuggerBrowsableAttribute:
public class User
{
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public string Login { get; set; }
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
public FullName Name { get; set; }
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public string HashedPassword { get; set; }
}
As you see property HashedPassword will be hidden from debugging.
Also, you can use Watch window in Visual Studio and configure your variable which you want to track.
You can use the DebuggerDisplay attribute to control how data is displayed in the tooltip whilst debugging e.g.
[DebuggerDisplay("Age = {Age}, Name = '{Name}'")]
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
For reference:
Using the DebuggerDisplay Attribute
DebuggerDisplay attribute best practices
I've playing around with a class that acts as a public interface for a private List<T> attribute. I noticed that the List<> class has an attribute Length that tells you how many elements it contains.
This is an attribute you cannot alter, and on the intellisense appears with an image of a spanner next to it. It is not a method as it does not require () after coding the name.
I've seen attributes of this type before, but never used them in my own classes. Does anybody have any idea how I can replicate Length in my custom class?
Thanks,
Mark
It's a property with no setter. If you're wrapping a List<T> you can just use it's Count as your own:
public int Count {get {return _myPrivateList.Count; } }
If you're using C# 6, you can use this:
public int Count => _myPrivateList.Count;
If you currently have a class that contains a List, then you can take advantage of the Count property already present on it by exposing a property that simply uses that :
public class YourExampleList<T>
{
// Example of your inner list
private List<T> _list { get; set; }
// Use the Count property to expose a public "Length" equivalent
public int Length { get { return _list.Count; } }
}
This is actually not a method, but a property.
So you could have define in your class
private List<string> myList = new List<string>();
public int NumberOfElements
{
get { return this.myList.Count; }
}
A normal property would be defined such as
public bool ColumnNames { get; set; }
List<T> myList = new List<T>();
Now you can create your own implementation on your custom class. Something like:
public int Length {get {return myList.Count; }}
I must admit that your question is a bit vague. It sounds like you want know how to create a read only attribute / property. This can be achieved by creating a property wrapper for a private field member of your class as follow:
class MyCustomClass
{
private int _length;
public int Length
{
get { return _length; }
}
}
Say for example you have a class like this:
public class MyClass
{
private string _str;
public MyClass()
{
_str = "Sample String";
}
public int Length
{
get
{
return _str.Length;
}
}
}
This is what's happening:
We're declaring a private field at the start of the class named _str.
In the constructor we're then assigning it a value of "Sample String".
After the constructor we're then declaring the public attribute Length of type int, and only giving it a get accessor. Like your example, this only allows the value to be read, and not set.
Within the get we then tell it to return the value of _str's length.
Using code similar to this you can implement a Length attribute for any custom class.
So I have this struct:
public struct PurchaseOrderStatus {
public const string Open = "Open", Received = "Received";
}
How do I convert if I have the following:
string status = "Open";
To:
PurchaseOrderStatus.Open;
By Convert, I mean, how do I do this:
PurchaseOrderStatus POS;
String status = "Open";
POS = status;
I would suggest using "smart enums" here:
public sealed class PurchaseOrderStatus
{
public static readonly PurchaseOrderStatus Open =
new PurchaseOrderStatus("Open");
public static readonly PurchaseOrderStatus Received =
new PurchaseOrderStatus("Received");
private readonly string text;
public string Text { get { return value; } }
private PurchaseOrderStatus(string text)
{
this.text = text;
}
}
You can store arbitrary information here, including text which wouldn't be valid identifiers (so long as it doesn't change, of course). It's still strongly typed (unlike your strings) and you can give other behaviour to it. You can even create subclasses if you remove the sealed modifier and add the subclasses as nested classes so they still have access to the private constructor.
Oh, and there's a genuinely limited set of values (the ones you've defined and null) unlike with regular enums.
The only downside is that you can't switch on it.
I have a Vote class and one of the properties it can have is a vote type. Such as unanimous, a 3/4 vote, a simply majority, etc. Each type needs to have a string associated with it which will describe the vote type (like "A simply majority requires 51% to pass" etc.). I need to pass these vote types/description in with my view model to my view and then I can make my drop down list with it.
Then, when the form that creates the vote is submitted I just need to bind the vote type (without description) to the Vote model (which is part of the view model).
I've only been using C# for a short time and I don't quite understand how the enums work in it. Perhaps enum is not the way to go about this.
public class VoteViewModel
{
public VoteViewModel()
{
Vote = new Vote();
}
public Vote Vote { get; set; }
public int EligibleVoters { get; set; }
}
And this is where I'll be putting the drop down.
<section class="vote-type">
<select name="">
<option value="">Select Vote Type</option>
</select>
<section class="vote-type-info">
<p class="vote-rules">To pass this vote, at least 51% of Eligible Voters must vote to approve it.</p>
</section>
</section>
Please notice I'm only showing for strings for it could be any type. In each case I mention how to extend it for more values if possible.
Using the enum as a key
You can use your enum type as a key for a dictionary (you want to be unique, so make it static and readonly in some helper class):
private static readonly Dictionary<MyEnum, string> _dict =
{
//Using dictionary initialization
{MyEnum.MyValue, "The text for MyValue"},
{MyEnum.MyOtherValue, "Some other text"},
{MyEnum.YetAnotherValue, "Something else"}
}
public static readonly Dictionary<MyEnum, string> Dict
{
get
{
return _dict;
}
}
And access the associated value:
string text = Dict[MyEnum.MyValue];
Or with:
string text;
if (Dict.TryGetValue(MyEnum.MyValue, out text))
{
//It has the value
}
else
{
//It doesn't have the value
}
This way you can access a string that is associated with the enum value. Then you can expose your Dictionary so that you can read the corresponding values.
You will need a complex type for storing more than one value. Just use your custom type isntead of string. Or if available you can use Tuples.
Accesing the Dictionary may mean an extra annoyance and hopefully it will not mean a threading problem too.
Enum.GetName
You can use Enum.GetName to read the name of the values of your enum:
string text = Enum.GetName(MyEnum.MyValue);
//text will have the text "MyValue"
//or
var some = MyEnum.MyValue;
string text = Enum.GetName(some);
Note: ToString() should work too.
Sadly, this will not work for something else than the string.
Also it has the drawback that you cannot put any text there (it has to be a valid identifier).
Custom Attributes
You will have to declare an attribute type:
[AttributeUsage(AttributeTargets.Field)]
public class EnumValueAttribute : System.Attribute
{
public readonly string _value;
public string Value
{
get
{
return _value;
}
}
public EnumValueAttribute(string value) // value is a positional parameter
{
//beware: value can be null...
// ...but we don't want to throw exceptions here
_value = value;
}
}
Now you apply the attribute to your enum:
public enum MyEnum
{
[EnumValue("The text for MyValue")]
MyValue = 1,
[EnumValue("Some other text")]
MyOtherValue = 2,
[EnumValue("Something else")]
YetAnotherValue = 3
}
Lastly you will need to read the attribute back:
public static string GetValue(MyEnum enumValue)
{
FieldInfo fieldInfo = typeof(MyEnum).GetField(enumValue.ToString());
if (!ReferenceEquals(fieldInfo, null))
{
object[] attributes = fieldInfo.GetCustomAttributes(typeof(EnumValueAttribute), true);
if (!ReferenceEquals(attributes, null) && attributes.Length > 0)
{
return ((EnumValueAttribute)attributes[0]).Value;
}
}
//Not valid value or it didn't have the attribute
return null;
}
Now you can call it:
string text1 = GetValue(MyEnum.MyValue);
//text1 will have the text "MyValue"
//or
var some = MyEnum.MyValue;
string text2 = GetValue(some);
You can add more fields to your attribute class and use them to pass any other value you may need.
But this requires reflexion, and it may not be available if you are running in a sandbox. Also it will retrieve the attributes each time, creating some short lived objects in the proccess.
Emulate Enum
You can emulate an enum with a sealed class that has no public constructor and exposes static readonly instances of itself:
public sealed class MyEnumEmu
{
private static readonly string myValue = new MyEnumEmu("The text for MyValue");
private static readonly string myOtherValue = new MyEnumEmu("Some other text");
private static readonly string yetAnotherValue = new MyEnumEmu("Something else");
public static MyEnumEmu MyValue
{
get
{
return myValue;
}
}
public static MyEnumEmu MyOtherValue
{
get
{
return myOtherValue;
}
}
public static MyEnumEmu YetAnotherValue
{
get
{
return yetAnotherValue;
}
}
private string _value;
private MyEnumEmu(string value)
{
//Really, we are in control of the callers of this constructor...
//... but, just for good measure:
if (value == null)
{
throw new ArgumentNullException("value");
}
else
{
_value = value;
}
}
public string Value
{
get
{
return _value;
}
}
}
Use it as always:
var some = MyEnumEmu.MyValue;
And access the associated value:
string text = MyEnumEmu.MyValue.Value;
//text will have the text "MyValue"
//or
string text = some.Value;
This is the more flexible of all, you can either use a complex type instead of string or add extra fields for passing more than a single value.
But... it is not really an enum.
You could create a "constant" dictionary (or rather readonly static, since you can't create a constant dictionary) around your Enum.
public enum VoteType { Unanimous = 1, SimpleMajority = 2, ... }
public static readonly Dictionary<VoteType, string> VoteDescriptions = new Dictionary<VoteType, string>
{
{ VoteType.Unanimous, "Unanimous description" },
{ VoteType.SimpleMajority, "Simple majority" },
...
};
public class Vote()
{
public VoteType VoteSelectType { get; set; }
}
public enum VoteType
{
[Display(Name = "Enter Text Here")]
unanimous = 1,
[Display(Name = "Enter Text Here")]
threequatervote = 2,
[Display(Name = "Enter Text Here")]
simplymajority = 3
}
Goto here this is pretty much your solution
How do I populate a dropdownlist with enum values?
You can use enums if you want but you need to decide how to make the link between the enum value and what you want to display. For example, an enum value of SimpleMajority you would want displayed as "Simple Majority". One way to do this is using the Description attribute and a helper class as described here.
However, you might find it easier to set up a lightweight collection class to store vote type values and their description. This could be as simple as a Dictionary<int, string> You will probably find this a more straightforward approach.
Since you have the type and description I'll better suggest you to create a class that wraps up both instead of enum. The advantage is you can reduce more work and it's very flexible.
public class VoteType
{
public string Name{ get; set; }
public string Description{ get; set; }
}
Now your Vote class will have reference to this VoteType.
public class Vote
{
...
public VoteType Type{ get; set; }
}
In your VoteViewModel you better have a class that contains all the VoteTypes.
public class VoteViewModel
{
...
public IEnumerable<SelectListItem> VoteTypes{ get; set; }
}
Now you can easily bind the VoteTypes in a dropdownlist.
#model VoteViewModel
#Html.DropDiwnListFor(m => m.VoteTypes,...)
I have used this before, it is really handy.
http://www.codeproject.com/Articles/13821/Adding-Descriptions-to-your-Enumerations
In short what it lets you do is:
public enum MyColors{
[Description("The Color of my skin")]
White,
[Description("Bulls like this color")]
Red,
[Description("The color of slime")]
Green
}
and then get the description back by simply calling:
String desc = GetDescription(MyColor.Green);
It does use reflection though, so there is a tradeoff between simplicity and a slight performance hit. Most of the time I'd take the performance hit...
Can somebody help me understand the get & set?
Why are they needed? I can just make a public variable.
Warning: I am assuming you already know about object-oriented programming.
What are properties?
Properties are language elements that allow you to avoid the repetitive getXYZ() accessors and setXYZ() mutators techniques found in other languages, like Java.
Why do they exist?
They aim to solve the following problems:
Saying get and set in the beginning of every access or mutation of a value is annoying and distracting.
In Java, you often say:
class person
{
private int _age;
public void setAge(int value) { /*check value first, then set _age*/ }
public int getAge() { return this._age; }
}
and then consistently say:
if (person.getAge() > blah || person.getAge() < 10)
{
person.setAge(5);
}
After a while, the get and set become rather annoying.
Providing direct access to the actual variable breaks encapsulation, so that's not an option.
How are they used?
They are used just like variables. You read/write to them just like variables.
How are they created?
They are created as methods. You define a pair of methods that:
Return the current value of the property. Oftentimes, this is nothing more than something like the following:
class Person
{
private int _age; //Declare the backing field
public int Age
{
get { return this._age; }
set { ... }
}
}
Set the value of the property:
class Person
{
public int Age
{
get { ... }
set
{
if (value < 0) //'value' is what the user provided
{ throw new ArgumentOutOfRangeException(); } //Check validity
this._age = value;
}
}
}
Other notes:
Auto-implemented Properties
C# 3.0 introduced auto-implemented properties:
public int Age { get; set; }
This is equivalent to:
private int _age; //The name is auto-generated
public int Age { get { return this._age; } set { this._age = value; } }
Why does it exist?
It helps you avoiding breaking changes in client executables.
Let's say you're lazy and don't want to type the whole thing, and decide to expose a variable publicly. You then create an executable that reads from or writes to that field. Then you change your mind and decide that you in fact needed a property, so you change it to one.
What happens?
The depending executable breaks, because the code is no longer valid.
Auto-implemented properties help you avoid that, without extra redundancy in your initial code.
Indexers
Indexers extend the property syntax to let you index objects (surprise!), just like arrays.
For C++ users: This is similar to overloading operator [].
Example:
private int[] _elements;
public int this[int index] //Indexed property
{
get { return this._elements[index]; }
set
{
//Do any checks on the index and value
this._elements[index] = value;
}
}
You then use them like obj[5] = 10;, which is equivalent to calling the set method of obj's indexer.
In fact, System.Collections.Generic.List<T> is indexed:
var list = new List<int>();
list.Add(10);
list[0] = 5; //You're indexing list, as though it were an array!
Isn't that neat? :)
Anything else?
There are many more features to properties, not all of which are available in C#:
Parametrized properties, of which indexers are a special kind
Getter/setter access modifiers (in C#)
Multiple getters or setters (not in C#)
Et cetera
They are called Accessors
The accessor of a property contains the executable statements associated with getting (reading or computing) or setting (writing) the property. The accessor declarations can contain a get accessor, a set accessor, or both.
The body of the get accessor resembles that of a method. It must return a value of the property type.
http://msdn.microsoft.com/en-us/library/w86s7x04.aspx
private string m_Name; // the name field
public string Name // the Name property
{
get
{
return m_Name;
}
}
The set accessor resembles a method whose return type is void. It uses an implicit parameter called value, whose type is the type of the property.
private m_Name;
public string Name {
get {
return m_Name;
}
set {
m_Name = value;
}
}
Then in the incarnation of C# 3, you can do this much easier through auto-properties
public string Name {get; set; } // read and write
public string Name {get; } // read only
public string Name { get; private set; } //read and parent write
http://msdn.microsoft.com/en-us/library/bb384054.aspx
Properties act as accessors to the internal state of an object, hiding the implementation of that state.
So, for example, you may have a first name property in a class
public class Example
{
private string firstName;
public string FirstName
{
get {return this.firstName;}
}
}
So anyone using the class doesn't need to know how first name is stored, they just know they can get a string representation of it. By adding a set you also add a mutator, something which changes an objects internal state
public class Example
{
private string firstName;
public string FirstName
{
get {return this.firstName;}
set {set this.firstName = value;}
}
}
Again you're still isolating how the first name is stored internally (encapsulation), but users can change it by passing in a string.
Simply put, get and set accessors are the functions called on a Property; that is, when you retrieve the value or when you set it. It forces a type of behavior on the way values are retrieved or set.
For example, you may want to have a mechanism to get/set passwords. Generally speaking, you'll only want to compare the hash of a password instead of storing things plaintext, so you'd have the getter variable retrieve the stored hash, and the setter would take the provided input and hash it for storage.
Here's what I mean:
public class User {
//Usery properties here, and...
private string _password;
public string Password {
get {
return _password;
}
set {
_password = SomeHashingFunction(value);
}
}
}
value is the variable provided to the setter from what has been given in the variable assignment. e.g.: someuser.Password = "blah";
Get and set are used in properties. They can each be public, protected, or private. Similar to accessor and mutator methods, they allow some computation when code tries to access/mutate the property. Of course, as long as you define one of get/set, the other is optional.
Example without properties:
private int test;
public int getTest() {
// some computation on test here, maybe?
return test;
}
private void setTest(int test) {
// some error/range checking, maybe?
this.test = test;
}
With properties:
private int test;
public int Test {
get {
// some computation on test here, maybe?
return test;
}
private set {
// some error/range checking, maybe?
test = value; // value is a keyword here
}
}
get{} and set{} are accessors that offer up the ability to easily read and write to private fields. Working with a simple example:
public class Foo()
{
//Field
private int _bar;
//Property
public int Bar
{
get { return _bar; }
set { _bar = value; }
//value is an implicit parameter to the set acccessor.
//When you perform an assignment to the property, the value you
//assign is the value in "value"
}
}
In this case, Bar is a public property that has a getter and a setter that allows access to the private field _bar that would otherwise be inaccessible beyond class Foo.
Now in a class that has an instace of Foo, you can do this:
public class IHasAFoo()
{
private Foo _myFoo = new Foo();
public void SomeMethod()
{
_myFoo.Bar = 42;
}
}
So the public accessor allows you to set the value of the private field back in Foo.
Hope that helps!