C# - Serialize Constants with DataContractJsonSerializer - c#

I'm having the following class:
[DataContract]
class ExampleClass
{
//Properties
[DataMember(Name = "method")]
private const string method = "Example Constant";
...
...
The DataContractJsonSerializer don't seem to include the constant "method" in the JSON output.
How can I keep the member constant, and cause the class to serialize it?
Thank you.

For the JSON-output the const is not accessable at all as it´s private. However serializing a const makes no sense at all, as a const is a static member and belongs to the class itself, not to a specific instance. Therefor the serializer can´t set it on an instance as there is nothing to set on that instance.
Having said this you may wrap your constant in a property:
[DataContract]
class ExampleClass
{
private const string method = "Example Constant";
//Properties
[DataMember(Name = "method")]
public string Method { get; set; }
public ExampleClass(this.Method = method; }
}
PS.: I´m not familiar with contract-serializers, but this is what you would do with an Xml-serializer. Maybe with contract-ser you can also have a get-only property thus you won´t need the extra constructor, but I´m not sure about this.

const is a special keyword in .NET. If you specify field as constant, it would not exist in compiled code, but all the references of constant would be replaced with values of constant at compile time. Therefore this constant does not exist in compiled code and so it is not serialized as well.
The easiest way to fix it is to change constant to regular field (or property) and assign the value in constructor:
[DataContract]
class ExampleClass
{
public ExampleClass()
{
method = "Example Constant";
}
[DataMember(Name = "method")]
private string method;
Alternatively, you can use property:
[DataMember(Name = "method")]
private string Method { get; set; }

Constants are like normal variables. The only difference is that they will replace with the value on compile time.
JSON is a format for transporting data, therefore it does not have any reason for doing something special about constants. But if you have special types like classes or even enums where the name make a difference in the meaning, then there will be additional properties in JSON

Related

Encapsulation C# newbie

New to C#, and I understand that encapsulation is just a way of "protecting data". But I am still unclear. I thought that the point of get and set accessors were to add tests within those methods to check to see if parameters meet certain criteria, before allowing an external function to get and set anything, like this:
private string myName;
public string MyName;// this is a property, speical to c#, which sets the backing field.
private string myName = "mary";// the backing field.
public string MyName // this is a property, which sets/gets the backing field.
{
get
{
return myName;
}
set
{
if (value != "Silly Woman"){
myName = value;
}
}
}
But I've been seeing code in c# which just looks like this:
public string MyName { get; set; }
Why would you just have a get and set with nothing in there, - isn't that the same as just declaring your private backing field public? If you can just get and set it from outside, why wouldn't you just do it directly?
Indeed, creating an auto-property as follows:
public string Name { get; set; }
is identical to building a property backed by a field:
private string _name;
public string Name {
get { return _name; }
set { _name = value; }
}
The point of these properties is not to hide data. As you observed, they don't do this. Instead, these properties can do other stuff instead of just working with a field:
public string Name {
get { return _name; }
set { if (value == null) throw new Exception("GTFO!"); _name = value; }
}
Another thing is, you can make properties virtual:
public virtual string Name { get; set; }
which, if overridden, can provide different results and behaviours in a derived class.
By using public string MyName { get; set; }, you leave an ability to change its logic later without the need to recompile/change other code that uses your property.
For example, if you are making a library and v1 uses a field and v2 uses a property, applications that work with v1 will not work with v2 without recompilation (and, potentially, code changes if they are written in some .NET language that has different syntax for accessing fields).
Another important difference is in serialization scenarios -- a lot of them do not support fields. Also any interface that requires a property can not be implemented without using one, but depending on interface it may not be required to do any additional checks/logic in it.
It makes it easier to add logic later. If you have a class that has a public field that you want to change to a property, you have to recompile everything that uses your class. That's a key point that I didn't understand initially.
If you have a class:
public class MyClass
{
public string MyString;
}
You could access the value like this:
var myClass = new MyClass();
string s = myClass.MyString;
Now change that to a property:
public class MyClass
{
public string MyString { get; set; }
}
How is it accessed? The exact same way:
var myClass = new MyClass();
string s = myClass.MyString;
So no big deal, right? Well, actually....
Properties are actually compiled into getter and setter methods:
get_MyString() and set_MyString(string value)
So the two methods do produce different compiled code. Now if all your code that uses this class is in the same project, is not as big a deal, because it will all be compiled together. But if you have an API library that you've distributed, it can be a much bigger deal to update.
Because it is easier to change the Code if you want to add the checks/tests later on.
Especially if you have many inheritance and many classes in your code it is very hard to change the implementation from a public variable to a public Property.
Moreover you can add to the get and set within the property different attributes, e.g. if you are using reflection. The get and set of the property are internally different methods. If you have just a public variable /field it is not possible to added different properties to the different access ways.
Yeah, but you can easily change it to:
public string MyName { get; private set; }
Plus, properties are used in other scenarios, like DataContracts and Serialization... so, this is a nice feature... (Mostly, syntactic sugar. I think) EDIT: I take that back.. you can apply virtual to it, so it's not the same

How can I assign a property to an attribute

I would like to assign a property string to below attribute.
[ExtractKeyAttribute(**"Extraction"**)]
public class Extract
{
....
}
so extraction is my string but I don't want hard code into there. Any suggestions on better way to assign
You can't do this.
Attribute values must be constant expressions. The values are baked into the compiled code. If you don't want to use a constant expression, you can't use an attribute... and you possibly shouldn't. It may mean you're using attributes when you should be using a different approach.
You might want to read Eric Lippert's blog post on properties vs attributes.
Of course, you don't have to use a string literal there. You could have:
[ExtractKey(ExtractionKeys.Extraction)]
...
public static class ExtractionKeys
{
public const string Extraction = "Extraction";
}
... but it's still a compile-time constant.
In your comments you say you have all (string) values in a static class. Is your static class a class with readonly properties? I mean, do the values change? If not, replace some of those properties in your static class with const strings values. U can use these values to set your attribute.
So...
static class MyClass
{
public string MyValue {get;}
}
would become:
static class MyClass
{
public const string MyValue= "MyValue";
}
Now your attribute can be set as follows:
[ExtractKey(MyClass.MyValue)]
If you want to modify the property of your attribute during runtime, then you can do this with this code:
ExtractKeyAttribute myAttribute = typeof(Extract).GetCustomAttributes(typeof(ExtractKeyAttribute), false)[0] as ExtractKeyAttribute;
myAttribute.MyValue = "MyRunTimeValue";

Properties in a Class

What is the difference (i.e. advantage/disadvantage) between the 2 properties that I created? Both seem to be correct, but what is the best way (practice) of declaring properties in a class?
[Serializable]
public class MySample
{
public string String1 = string.Empty;
private string _string2 = string.Empty;
public string String2
{
get { return _string2 ; }
set { _string2 = value; }
}
}
Only String2 is a property, the other is a public field.
See Difference between Property and Field in C# .NET 3.5+ for detail but if in doubt you should use properties rather than public fields.
If that seems like too much typing then you will be pleased to know that the following is equivalent
public string String2 { get; set; }
See auto-properties
Only String2 is a property. String1 is just a public field, and it is recommended to not declare public fields.
You can simplify the declaration of simple properties like this by using automatic properties:
public string String { get; set; }
The main difference between fields and properties is that fields are accessed directly, whereas properties are read and written to via get and set methods. When you declare an automatic property as above, these get and set methods are automatically generated for you by the compiler, as well as a backing field to store the actual value.
You can also execute additional code in the get and set methods, which is often used for things like change notification and validation. You can set the get and set methods to different visibilities, such as { get; private set; }, which is another thing that you don't have with fields.
Note that even if the usage of String1 and String2 in your example is the same, they are not binary compatible. That is, if you have a class that uses a field and you want to change that field to a property, you'll need to recompile all assemblies referencing that class. So it's best to go with (at least automatic) properties from the beginning.
The best way is to use auto-properties:
like this:
public string String1 {get;set;}
If you want a property from which you only read from, but not write to:
public string String1 {get; private set;}
If you want a property to which you only write to, but not read from:
public string String1 {set; private get;}
Generally it is recommended that you should not declare fields as public:
public string _string1; /*bad idea*/
The first this is that :
public string String1 = string.Empty;
is a field, not a property. You should generally avoid making public fields.
The second is a property with a field backer. This can be useful if you want to do some sort of validation before setting it. Or maybe have some sort of lazy initialisation before getting the value (obviously the lazy initialisation works better for more complex types or where the construction of the value, if not needed often, takes time).
The third option is an auto property, like this:
public string String3 { get; set; }
This compiles like a property, so if you change your code to be a field backed property to add extra functionality, then the signature of your class doesn't have to change and any existing code that uses the class won't need to be updated to call a property instead of a field (since it always was a property)
The first is not a property, but a field. The way you've implemented these here, there's effectively no difference, but in general, properties give you a lot more power.
See What is the difference between a Field and a Property in C#?
The usual way to implement a property in C# is:
public string String1 { get; set; }
Your String1 is actually a field, not a property. I suppose you were wanting an auto-implemented property, such as:
public string String1 { get; set; }
Your String2 is a field-backed property. One of the main differences between the two is that you have the opportunity to initialize the field-backed property by initializing the field instead of initializing the property in the constructor. Another important difference is that you have the opportunity in the field-backed property to do other things when the value is retrieved or set, such as performing change notification.
String1 is a public field, not a property. This is not recommended unless it's static readonly (and immutable!), like String.Empty.
Even if a field is fine now (though propably not state-of-the-art), changing it into a property later on breaks the binary compatibility of your class and thus is a breaking change.

C# pre initialized class

What is the best practice to create pre-initialized class. For example
Chip chip = new Atmega8();
I would like to have its properties already defined like:
chip.Name = "Atmega8 AVR Chip";
and so on.
How to achieve it in C#?
Should I use readonly public properties or property with private set?
Have your constructor initialize the values:
class Atmega8 {
public Atmega8 ()
{
Name = "Atmega8 AVR Chip";
}
public string Name { get; set; }
}
If you intend Name to be the same for all instances, it might make sense to declare it abstract in the base class and override the getter:
abstract class Chip {
public abstract string Name { get; }
}
class Atmega8 : Chip {
public override string Name {
get { return "Atmega8 AVR Chip"; }
}
}
Because we haven't defined a set method, the value cannot be changed, much like a readonly variable except it isn't even stored anywhere and just returned on each call.
If you want the compiler to enforce that nothing can change the value of the field once initialized, then set it up as a read-only field, and populate it in the constructor of the class (or simply initialize it when you declare it; this doesn't work so well with inheritance though). If you don't care as long as nothing OUTSIDE the object can change it (meaning you will trust your own coding discipline to ensure it doesn't change internally), a get-only property with a backing field, or an auto-property with a private setter, are your bets.
IF you absitively posolutely DO NOT WANT the value to change for a particular class, EVER, then I would make it a get-only property returning either a string literal or a constant. I would recommend using the constant over the literal, as you can put the constants into their own static class which you can then use separately from each Chip class.
HOWEVER, there's a quirk of constants you should know. A constant value in .NET is stored in the manifest of not only the assembly containing the declaring code, but in every assembly that references the declaring assembly. Each assembly's code them uses the value from its own manifest. So, if the constant value EVER changes, any assembly that references the declaring assembly must be recompiled to update those assemblies' manifests with the new value. Otherwise, the constant will only have its new value when used from within the declaring assembly. For this reason, labeling a variable as constant should not be done lightly. Personally, my opinion is if the constant isn't some value on which the continued existence and functioning of the universe depends, like pi, e, the speed of light in a vacuum, Plank's Constant, Avogadro's Number, etc, then it isn't "constant". Anything else, like communication code ordinals, CAN change, even if doing so would break compatibility with every previous version of your program.
Depends what you want to accomplish.
It looks like you never want the value of Name to change. One approach would be to declare Name as abstract in Chip, and implement Name in each child class to return a constant string value.
abstract class Chip
{
public abstract string Name { get; }
}
class Amiga8 : Chip
{
public override string Name { get { return "Atmega8 AVR Chip"; } }
}
class Program
{
static void Main(string[] args)
{
Chip chip = new Amiga8();
Console.WriteLine(chip.Name);
}
}
In the constructor of the Atmega8 class you can set a property to something. Ie:
public Atmega8() {
Name = "Atmega8 AVR Chip";
}
If you do not want that to be changed in runtime you could mark the property as readonly ( only assignable through a constructor of declarative ).
private readonly string _Name = string.Empty;
public string Name {
get { return _name; }
}
public Atmega8() {
_Name = "Atmega8 AVR Chip";
}
Value of property cannot change -> Read-only public property.
Value of property can change -> Property with private set
If you don't want it to change, make the Name property a const or readonly on the Atmega8 class. Private set still allows the Name to change internally.
You're saying that you want the class to be populated at the same time it's initialized? Just populate the object in the constructor, like so:
class Test
{
public Test()
{
this.Name = "Hello World";
}
//if you need to pass information into the constructor:
public Test(string testName)
{
this.Name = testName;
}
}
Then, you can do this to initialize it:
Test test = new Test(); //default name of Hello World!
OR
Test test = new Test("Bingo!");

CA1019: Define accessor for attribute argument. I don't understand the reason

Today, I was cleaning up some of my code with FXCop and it complained about a Attribute class I had with this violation.
CA1019: Define accessor for attribute argument.
On this page, http://msdn.microsoft.com/en-us/library/ms182136.aspx there is more information, but I still do not get the reason for this as it seems to me more verbose and less relevant.
It gives two codes samples.
using System;
namespace DesignLibrary
{
// Violates rule: DefineAccessorsForAttributeArguments.
[AttributeUsage(AttributeTargets.All)]
public sealed class BadCustomAttribute :Attribute
{
string data;
// Missing the property that corresponds to
// the someStringData parameter.
public BadCustomAttribute(string someStringData)
{
data = someStringData;
}
}
// Satisfies rule: Attributes should have accessors for all arguments.
[AttributeUsage(AttributeTargets.All)]
public sealed class GoodCustomAttribute :Attribute
{
string data;
public GoodCustomAttribute(string someStringData)
{
data = someStringData;
}
//The constructor parameter and property
//name are the same except for case.
public string SomeStringData
{
get
{
return data;
}
}
}
}
I don't understand why the SomeStringData property is required. Isn't the someStringData a parameter? Why does it need to have its own property if it is already stored in another property?
Actually, mine is a little different as it looks like this.
[AttributeUsage(AttributeTargets.Property)]
public sealed class ExampleAttribute : Attribute
{
public ExampleAttribute(string attributeValue)
{
this.Path = attributeValue;
}
public string Name
{
get;
set;
}
// Add to add this to stop the CA1019 moaning but I find it useless and stupid?
public string AttributeValue
{
get
{
return this.Name;
}
}
}
Rather than a private field, I have used a public autoproperty, I had to add the last part to make the warning stop but I don't see the point and it also adds another public field to this class, which is redundant, and seems less clean.
That said, I assume that this warning is raised for a reason so what good reason I am missing here?
Thanks in advance.
FxCop is complaining because your existing property doesn't match the parameter name.
Therefore, it doesn't realize that the parameter actually is exposed.
You should rename the property or parameter to match (except for case), or suppress the warning.
FxCop rule CA1019 is just enforcing the .Net Framework coding guidelines for Attributes.
Use named arguments (read/write properties) for optional parameters. Provide a read/write property with the same name as each named argument, but change the case to differentiate between them.
Documentation Link: http://msdn.microsoft.com/en-us/library/2ab31zeh(v=vs.71).aspx
The reason behind the FxCop warning is that every piece of data you pass into the attribute's constructor should be made publicly available to access when the attribute instance is being retrieved by Reflection.
Let's say you have this:
[BadCustom("My String Data")]
public class DecoratedClass
{
}
How will you get "My String Data" back from that attribute instance when you read it using:
BadCustomAttribute attr = typeof(DecoratedClass)
.GetCustomAttributes(typeof(BadCustomAttribute), false)
.Single() as BadCustomAttribute;
Now you have the instance of your attribute, but no way to read the string passed into the constructor because you didn't at least declare a read-only property for it.
the idea is that you should write just:
[AttributeUsage(AttributeTargets.Property)]
public sealed class ExampleAttribute : Attribute
{
public ExampleAttribute(string attributeValue)
{
this.AttributeValue = attributeValue;
}
public string AttributeValue
{
get;
set;
}
}
This violation will also be thrown when the parameter name matches the property name, but the data types are different.

Categories