Serializing arrays of objects with protobuf-net for C++ consumption - c#

I've build some classes as per instructed in the following answer here in order to be able to serialize a list of generic objects; such as instances of KeyValuePair and KeyValuePair.
Unfortunately, it appears that the .proto file generated by the GetProto() method does not generate a file that can be parsed properly for C++. Subtype messages generated for arrays are suffixed with "[]". The protoc.exe chokes on the "[]" when compiling for C++.
Since the message names seem to be arbitrary for protobuf (that is, they're not actually included in the data stream), is possible to tell protobuf-net to use "_Array" instead of "[]" when naming the sub-types? Or is there some other avenue I should take so that the .proto file generated can be consumed by a C++ application?
Thanks,
Below is the relevant code and generated proto file.
The base class is:
[DataContract]
[ProtoInclude(101, typeof(KeyValuePairResponse<string>))]
[ProtoInclude(102, typeof(KeyValuePairResponse<int>))]
[ProtoInclude(103, typeof(KeyValuePairResponse<double>))]
[ProtoInclude(111, typeof(KeyValuePairResponse<string[]>))]
[ProtoInclude(112, typeof(KeyValuePairResponse<int[]>))]
[ProtoInclude(113, typeof(KeyValuePairResponse<double[]>))]
public abstract class KeyValuePairResponse
{
protected KeyValuePairResponse() { }
[DataMember(Order = 1, IsRequired = true)]
public string Key { get; set; }
public object Value
{
get
{
return this.ValueImplementation;
}
set
{
this.ValueImplementation = value;
}
}
protected abstract object ValueImplementation { get; set; }
public static KeyValuePairResponse<T> Create<T>(string key, T value)
{
return new KeyValuePairResponse<T>(key, value);
}
}
and the generic class is:
[DataContract]
public sealed class KeyValuePairResponse<T> : KeyValuePairResponse
{
public KeyValuePairResponse()
{
}
public KeyValuePairResponse(string key, T value)
{
this.Key = key;
this.Value = value;
}
[DataMember(Order = 2, IsRequired = true)]
public new T Value { get; set; }
protected override object ValueImplementation
{
get
{
return this.Value;
}
set
{
this.Value = (T)value;
}
}
}
The .proto file that GetProto<KeyValuePairResponse>() creates looks like:
message KeyValuePairResponse {
required string Key = 1;
// the following represent sub-types; at most 1 should have a value
optional KeyValuePairResponse_String KeyValuePairResponse_String = 101;
optional KeyValuePairResponse_Int32 KeyValuePairResponse_Int32 = 102;
optional KeyValuePairResponse_Double KeyValuePairResponse_Double = 103;
optional KeyValuePairResponse_String[] KeyValuePairResponse_String[] = 111;
optional KeyValuePairResponse_Int32[] KeyValuePairResponse_Int32[] = 112;
optional KeyValuePairResponse_Double[] KeyValuePairResponse_Double[] = 113;
}
message KeyValuePairResponse_Double {
required double Value = 2 [default = 0];
}
message KeyValuePairResponse_Double[] {
repeated double Value = 2;
}
message KeyValuePairResponse_Int32 {
required int32 Value = 2 [default = 0];
}
message KeyValuePairResponse_Int32[] {
repeated int32 Value = 2;
}
message KeyValuePairResponse_String {
required string Value = 2;
}
message KeyValuePairResponse_String[] {
repeated string Value = 2;
}

This is simply a bug in GetProto. I suggest logging it on the github protobuf-net list, or even submitting a pull request if you're feeling adventurous.
For now: Ctrl+h (find and replace) is probably your friend.

Related

Enumeration Objects (Strings) in Entity Framework

I am building a model with Entity Framework and purchased responsive CSS.
The built in fixed icons comes with CSS. Like as follows (Name and Icon Class Value)
I need a way to keep the names of icons as fixed enums to access it from the VS intellisense. Currently we can't store as a entity table in entity framework (as it require relationship with tables difficult to maintain) and enum doesn't allows string type.
Code that did not work:
public sealed class IconType
{
public static readonly IconType Rupee_Icon = new IconType("rupee-icons");
public static readonly IconType Doller_Icon = new IconType("doller-icon");
private IconType(int EnumID,string EnumObjectValue)
{
IconValue = EnumObjectValue;
}
public string IconValue { get; private set; }
}
More code that did not work (CSS class names contains whitespaces like ui bell icon):
public enum Icon
{
NotSet=0,
Idea Icon=1,
Bell Icon =2
}
Is there any other ways to use names / objects as enums or constants in EF for easy intellisense in Visual Studio?
You could:
Omit the white spaces in the enums:
public enum Icon
{
NotSet = 0,
IdeaIcon = 1,
BellIcon = 2
}
Add a description or name (Or even some custom attribute) attributes to the enums:
public enum Icon
{
NotSet = 0,
[Description("ui idea icon")]
IdeaIcon = 1,
[Description("ui bell icon")]
BellIcon = 2
}
When needed get the description name. Example method to get the description attribute value:
public static string GetDescription<T>(this T enumerationValue)
where T : struct, IConvertible
{
var type = enumerationValue.GetType();
if (!type.IsEnum)
{
throw new ArgumentException("EnumerationValue must be of Enum type", "enumerationValue");
}
// Tries to find a DescriptionAttribute for a potential friendly name for the enum
var memberInfo = type.GetMember(enumerationValue.ToString(CultureInfo.InvariantCulture));
if (memberInfo.Length > 0)
{
var attributes = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes.Length > 0)
{
// Pull out the description value
return ((DescriptionAttribute)attributes[0]).Description;
}
}
// If we have no description attribute, just return the ToString of the enum
return enumerationValue.ToString(CultureInfo.InvariantCulture);
}
Did you consider using string constants?
public static class IconType
{
public const string RUPEE_ICON = "rupee-icon";
public const string DOLLER_ICON = "doller-icon";
// ...
}
Store the icon's as plain old objects. Why make use of entity framework at all?
public static class Icons
{
public enum Type
{
IdeaIcon = 1,
BellIcon =2
}
public static Icon Get(Type type)
{
return IconCollection.Single(icon => icon.Type == type);
}
static IEnumerable<Icon> IconCollection
{
get
{
return new List<Icon>
{
new Icon(Type.IdeaIcon, "Idea Icon", "icon idea-icon"),
new Icon(Type.BellIcon, "Bell Icon", "icon bell-icon"),
};
}
}
public class Icon
{
public Icon(Type type, string description, string cssClass)
{
Type = type;
Description = description;
CssClass = cssClass;
}
public Type Type { get; private set; }
public string Description { get; private set; }
public string CssClass { get; private set; }
}
}
Use in code:
public class Class1
{
public void Method1()
{
var ideaIcon = Icons.Get(Icons.Type.IdeaIcon);
var x = ideaIcon.CssClass;
var y = ideaIcon.Description;
var bellIcon = Icons.Get(Icons.Type.BellIcon);
// etc...
}
}
Razor view:
#Icons.Get(Icons.Type.BellIcon).CssClass
If you needed to enumerate over the icon collection you could easily add another static accessor to the Icons class.

Code snippet: create an "alias" for something else

I was looking for a similar way to create an alias for something else like its possible in C using preprocessor (this question is a bit similar, couldn't find anything useful there).
This is the problem: I've got a method that receives an array, but each position of the array has a specific meaning, like they where different parameters with specific names. What I want to do is to make my code easier to read (and write) by using those specific names, but, on the other hand, I don't want to create another method call (like in example 1) nor assign the array positions to new variables (example 2), because the performance is critical.
Example 1:
void OriginalMethodSignature(Type[] values)
{
SimplifiedMethod(values[0], values[1], ... values[n]);
}
void SimplifiedMethod(Type specificName1, Type specificName2, ... Type specificNameN)
{
// simple implementation using specific names instead of values[n]
}
Example 2:
void OriginalMethodSignature(Type[] values)
{
Type specificName1 = values[0];
Type specificName2 = values[1];
...
Type specificNameN = values[n];
// simple implementation using specific names instead of values[n]
}
I cannot change the method signature because its used in a dellegate, the Type is fixed.
The next example is a bit better, but still not optimum:
void OriginalMethodSignature(Type[] values)
{
// implementation using values[specificName1] ... values [specificNameN]
}
const int specificName1 = 0;
const int specificName2 = 1;
...
const int specificNameN = n-1;
Is there any way to create an snippet for this purpose? If yes, how would it be?
There isn't any built in way to do what you wan't, because you shouldn't really be doing it at all. You should be using an object with properties instead of an array.
Anyway, you can make an object that encapsulates the array, so that the properties use the array as storage:
public class NamedObject {
private Type[] _values;
public NamedObject(Type[] values) {
_values = values;
}
public SpecificName1 { get { return _values[0]; } set { _values[0] = value; } }
public SpecificName2 { get { return _values[1]; } set { _values[1] = value; } }
public SpecificName3 { get { return _values[2]; } set { _values[2] = value; } }
public SpecificName4 { get { return _values[3]; } set { _values[3] = value; } }
public SpecificName5 { get { return _values[4]; } set { _values[4] = value; } }
public SpecificName6 { get { return _values[5]; } set { _values[5] = value; } }
}
Now you can use the object to access the array:
void OriginalMethodSignature(Type[] values) {
NamedObject obj = new NamedObject(values);
// get a value
Type x = obj.SpecificName4;
// set a value
obj.SpecificName2 = x;
}
Create a dedicated class or struct, and parse the array into it.
public class MyClassOfStuff
{
Type SpecificName1 {get;set;}
Type SpecificName2 {get;set;}
public static MyClassOfStuff Parse(Type[] value)
{
Type specificName1 = values[0];
Type specificName2 = values[1];
...
Type specificNameN = values[n];
}
}
void OriginalMethodSignature(Type[] values)
{
var mystuff = MyClassOfStuff.Parse(values);
}

Reflection - object comparison & default values

I'm trying to compare two complex objects in C#, and produce a Dictionary containing the differences between the two.
If I have a class like so:
public class Product
{
public int Id {get; set;}
public bool IsWhatever {get; set;}
public string Something {get; set;}
public int SomeOtherId {get; set;}
}
And one instance, thus:
var p = new Product
{
Id = 1,
IsWhatever = false,
Something = "Pony",
SomeOtherId = 5
};
and another:
var newP = new Product
{
Id = 1,
IsWhatever = true
};
To get the differences between these, i'm doing stuff that includes this:
var oldProps = p.GetType().GetProperties();
var newProps = newP.GetType().GetProperties();
// snip
foreach(var newInfo in newProps)
{
var oldVal = oldInfo.GetValue(oldVersion, null);
var newVal = newInfo.GetValue(newVersion,null);
}
// snip - some ifs & thens & other stuff
and it's this line that's of interest
var newVal = newInfo.GetValue(newVersion,null);
Using the example objects above, this line would give me a default value of 0 for SomeOtherId (same story for bools & DateTimes & whathaveyou).
What i'm looking for is a way to have newProps include only the properties that are explicitly specified in the object, so in the above example, Id and IsWhatever. I've played about with BindingFlags to no avail.
Is this possible? Is there a cleaner/better way to do it, or a tool that's out there to save me the trouble?
Thanks.
There is no flag to tell if you a property was explicitly set. What you could do is declare your properties as nullable types and compare value to null.
If i understand you correctly, this is what microsoft did with the xml wrapping classes, generated with the xsd utility, where you had a XIsSpecified, or something like that, for each property X.
So this is what You can do as well - instead of public int ID{get;set;}, add a private member _id , or whatever you choose to call it, and a boolean property IDSpecified which will be set to true whenever Id's setter is called
I ended up fixing the issue without using reflection (or, not using it in this way at least).
It goes, more or less, like this:
public class Comparable
{
private IDictionary<string, object> _cache;
public Comparable()
{
_cache = new Dictionary<string, object>();
}
public IDictionary<string, object> Cache { get { return _cache; } }
protected void Add(string name, object val)
{
_cache.Add(name, val);
}
}
And the product implementation goes to this:
public class Product : Comparable
{
private int _id;
private bool _isWhatever;
private string _something;
private int _someOtherId;
public int Id {get { return _id; } set{ _id = value; Add("Id", value); } }
public bool IsWhatever { get { return _isWhatever; } set{ _isWhatever = value; Add("IsWhatever ", value); } }
public string Something {get { return _something; } set{ _something = value; Add("Something ", value); } }
public int SomeOtherId {get { return _someOtherId; } set{ _someOtherId = value; Add("SomeOtherId", value); } }
}
And the comparison is then pretty straightforward
var dic = new Dictionary<string, object>();
foreach(var obj in version1.Cache)
{
foreach(var newObj in version2.Cache)
{
//snip -- do stuff to check equality
dic.Add(....);
}
}
Doesn't hugely dirty the model, and works nicely.

How to support multiple custom types?

I have a Types project where I define custom class objects that I want to work on in my main application. The objects are basically derived from strings and parsed into a structure.
I have two problems
1 - In a separate project I have a File reader class where I scan text files for the string types I have defined. For example by regular expression. Currently I added my Types project as a project reference and I just list the regular expressions at the top of my read class. When i find a type I convert the string to the appropriate type. However how can i improve this so that is it directly connected to my Types project - so when i update it with new types the Read class knows that it should support the new types?
2 - I'm trying to create a DLL that works on these specific types after they are read from the text file. How do I tell my DLL that I want to support the types in my Types project? Do I have to make an overloaded function for each type I want to work on? Do I use an interface?
Any advice is greatly appreciated.
EDIT: Added example code of what I''m trying to do
//PROJECT 1 - handles IO operation like Reading and writing
//function in read class job is to find one of several predefined string types by regular expression...once found they are converted to the data structure (by passing string to constructor of type class defined in the other project
public class Read
{
public string[] FileList { get; set; }
private static Int64 endOffset = 0;
private FileStream readStream;
private StreamReader sr;
private System.Text.RegularExpressions.Regex type1 = new System.Text.RegularExpressions.Regex(#"#123:test");
private System.Text.RegularExpressions.Regex type2 = new System.Text.RegularExpressions.Regex(#"TESTTYPE2");
public Read(string[] fl)
{
FileList = fl;
}
public object ReturnMessage(FileStream readStream, out int x)
{
//readStream = new FileStream(file, FileMode.Open, FileAccess.Read);
x = 0;
//endOffset = 0;
bool found = false;
char ch;
string line = string.Empty;
object message = null;
while (!(x < 0)) //do this while not end of line (x = -1)
{
readStream.Position = endOffset;
//line reader
while (found == false) //keep reading characters until end of line found
{
x = readStream.ReadByte();
if (x < 0)
{
found = true;
break;
}
// else if ((x == 10) || (x == 13))
if ((x == 10) || (x == 13))
{
ch = System.Convert.ToChar(x);
line = line + ch;
x = readStream.ReadByte();
if ((x == 10) || (x == 13))
{
ch = System.Convert.ToChar(x);
line = line + ch;
found = true;
}
else
{
if (x != 10 && (x != 13))
{
readStream.Position--;
}
found = true;
}
}
else
{
ch = System.Convert.ToChar(x);
line = line + ch;
}
}//while - end line reader
//examine line (is it one of the supported types?)
if (type1.IsMatch(line))
{
message = line;
endOffset = readStream.Position;
break;
}
else
{
endOffset = readStream.Position;
found = false;
line = string.Empty;
}
}//while not end of line
return message;
}
}
//PROJECT 2 - contains classes that define the types
//TYPE1
namespace MessageTypes.Type1
{
public sealed class Type1
{
public List<Part> S2 { get; set; }
public Type1(string s)
{
S2 = new List<Part>();
string[] parts = s.Split(':');
for (int i = 0; i < parts.Length; i++)
{
S2.Add(new Part(parts[i]));
}
}
}
public sealed class Part
{
public string P { get; set; }
public Part(string s)
{
P = s;
}
}
}
//TYPE 2
namespace MessageTypes.Type2
{
public sealed class FullString
{
public string FS { get; set; }
public FullString(string s)
{
FS = s;
}
}
}
//PROJECT 3
class DoSomethingToTypeObject{
//detect type and call appropriate function to process
}
//PROJECT 4 -- MAIN PROJECT with GUI
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
if (tabControl1.SelectedIndex == 0) //Processing Mode 1
{
//load file list from main window - Mode1 tab
IOHandler.Read read = new IOHandler.Read(new string[2] { #"C:\file1.txt", #"C:\file2.txt" });
//read files
foreach (string file in read.FileList)
{
//while not end of stream
myobject = read.ProcessFile(file);
DoSomethingtoTypeObject DS = new DoSomethingtoTypeObject(myobject);
//write transoformed object
write(myobject);
}
}
}
}
You should use an interface, then make all of your types implement the interface. After doing that, you should then change your Read class to operate on the interface NOT the individual classes.
That way you can add as many types as you want and not have to update the Read class.
I hope I understand you correctly.
The class you create in the Type project represent some objects that have different behaviors but the same data members and you would like to be able to use these easily within your projects without the hassle of having to explicitly list these objects.
I would create some base interface that all my objects in the Types project would implement.
I would then use a Factory Class that would use reflection to collect all objects that implement said interface.
public interface iFoo
{
string FoundItem { get; set; }
string Expression { get; }
string Value { get; set; }
void sharedFunctionName();
}
public static class FooFactory
{
public static List<iFoo> GetTypeList()
{
List<iFoo> types = new List<iFoo>();
types.AddRange(from assembly in AppDomain.CurrentDomain.GetAssemblies()
from t in assembly.GetTypes()
where t.IsClass && t.GetInterfaces().Contains(typeof(iFoo))
select Activator.CreateInstance(t) as iFoo);
return types;
}
}
Then your Reader would receive all necessary information for the supported types without you having to manually dictate it anymore.
Since I guess the value type would be different at some point, you could use a Generic Interface like this :
public interface iFoo
{
string FoundItem { get; set; }
string Expression { get; }
void sharedFunctionName();
}
public interface iFoo<T> : iFoo
{
T Value { get; set; }
}
public static class FooFactory
{
public static List<iFoo> GetTypeList()
{
List<iFoo> types = new List<iFoo>();
types.AddRange(from assembly in AppDomain.CurrentDomain.GetAssemblies()
from t in assembly.GetTypes()
where t.IsClass && t.GetInterfaces().Contains(typeof(iFoo))
select Activator.CreateInstance(t) as iFoo);
return types;
}
}
public class FooBar : iFoo<int>
{
}
In this example the base interface iFoo is kept to ease the discovery process.
Using generic interface would allow to kept your code Type safe (as opposed to using a Value of type object) but you will have to add some logic when recovering your objects to be able to access your Value properly.
Plus, if you ever need to create functions that would require to be shared within all your objects you would be able to add extension methods within the Factory Class and VoilĂ .
EDIT:
Based on the new information:
Your Types correspond to a type of data that you will find in a file based on some regular expression.
There might be different type of transformation based on the user selection and the Type.
We know that the user will have to pick a mode from a list and this will affect the transformation to apply on the Types.
So this is what I would do :
I would move the transformation logic right into the Type class, polymophism will take care of exactly which transformation will be called.
I would put the RegularExpression to use to detect the Type into the Type itself, this will allow you to use reflection and the Factory class discuss earlier more easily.
This way, everything is standard. Your reader is aware of any new type you create in the type project without manual intervention and once detected the right transformation could be applied and the original string is always accessible.
public enum UserMode {Mode1, Mode2};
public interface iType
{
string Expression {get;}
string OriginalString {get; set;}
string Transform(UserMode Mode);
iType getNewInstance(string OriginalString);
}
public class Type1 : iType
{
public string Expression {get { return "RegularExpression"; }}
public string OriginalString {get; set;}
//Add any other private members you need to accomplish your work here.
public string Transform(UserMode Mode)
{
switch(Mode)
{
case UserMode.Mode1:
//write the transformation code for this scenario
return ResultString;
break;
}
}
public iType getNewInstance(string Original)
{
return (iType)(new Type1(){ OriginalString = Original });
}
}
public static class TypeFactory
{
public static List<iType> GetTypeList()
{
List<iType> types = new List<iType>();
types.AddRange(from assembly in AppDomain.CurrentDomain.GetAssemblies()
from t in assembly.GetTypes()
where t.IsClass && t.GetInterfaces().Contains(typeof(iType))
select Activator.CreateInstance(t) as iType);
return types;
}
}
Now, all you will have to do if match the expression from the iTypes in the list.
When you have a match you do :
var TransformationReady = from t in TypeFactory.GetTypeList()
where Regex.IsMatch(YourFileLine, t.Expression)
select t.getNewInstance(Regex.Match(YourFileLine, t.Expression));

Inheritance and Multiple Constructors

I have a question regarding inheritance, so I will describe the scenario below:
I am reading a text file containing logs. (One log per line)
Each log-line will have the following format:
"Date Type Description"
However, depending on the "Type" of log, I will have to parse the "Description" differently and pull out different fields.
Here are some examples:
5/1/2011 Information Field1, Field2, Field3
5/2/2011 Error Field1
--
So, what I tried to do was this:
-Get a line out of the log
-Parse it according to the pattern "Date Type Description"
-Look at the "Type" field, and create new objects/parse description as necessary
public class Log
{
public DateTime Date;
public String Type;
public String Description;
public Log(String line)
{
this.Date = GetDate();
this.Type = GetType();
this.Description = GetDescription();
}
}
public class InformationLog : Log
{
public String Field1;
public String Field2;
public String Field3;
public InformationLog(Log log)
{
this.Field1 = GetField1(log.Description);
this.Field1 = GetField2(log.Description);
this.Field1 = GetField3(log.Description);
}
}
public class Client
{
public void Main()
{
String line = ReadFileAndGetLine(); // Get a line from the file
Log log = new Log(line);
if(log.Type == "Information")
log = new InformationLog(log); // Is this right?
}
}
This works how I want it to, but it seems like this cannot be a good practice. The "log" variable is using itself as a parameter to its own constructor.
My question is:
Is there a standard way of doing this? Or, is there anything wrong with this implemenation?
--
Edit:
Also, I should mention: My reasoning was that I would parse the line once to get out the date and type, and then parse it again to get the finer details.
I decided to use inheritance so I wouldn't have to parse out the Date and Type fields twice.
Try to use Factory pattern
static class LogFactory
{
public static Log Create(String line)
{
if(GetType(line) == "Information")
return CreateInformationLog(line);
return CreateLog(line);
}
private static Log CreateLog(String line)
{
return new Log(line);
}
private static Log CreateInformationLog(String line)
{
return new InformationLog(line);
}
}
And then try to use
String line = ReadFileAndGetLine(); // Get a line from the file
Log log = LogFactory.Create(line);
As per my comment, why not just do something a little like this:
public enum LogEntryType
{
Error = -1,
Information = 0,
}
public class LogEntry
{
public string Raw;
public DateTime Date;
public LogEntryType Type;
public string Description;
public LogEntry(String line)
{
Raw = line;
Date = ParseDate();
Type = ParseType();
Description = ParseDescription();
}
public string ParseDescription()
{
var result = string.Empty;
switch(Type)
{
case LogEntryType.Error:
//parse here
break;
case LogEntryType.Information:
//parse here
break;
}
return result;
}
}
I notice you have fields in the derivative class, but the description could be parsed here; though, I can see why people may want to shift it to the place that actually knows how the description should be parsed, in which case you could use a factory pattern suggested in another answer, or implement a 'property bag' type scenario - but drifting away from strong typing is generally frowned upon these days, I reckon.
Another suggestion, though very similar to your initial attempt, tends to encapsulate management of the types, as opposed to having a detached class handle such stuff - a pattern a little (superficially) like Exception where you have a root entry and inner entries:
public enum LogEntryType
{
Error = -1,
Information = 0,
}
public class LogEntry
{
public string Raw;
public DateTime Date;
public LogEntryType Type;
public string Description;
public InnerLogEntry InnerEntry;
public LogEntry(String line)
{
Raw = line;
Date = ParseDate();
Type = ParseType();
//parse the 'raw' description...
Description = ParseDescription();
//determine the inner entry type...
switch (Type)
{
case LogEntryType.Error:
InnerEntry = new ErrorLogEntry(this);
break;
case LogEntryType.Information:
InnerEntry = new InformationLogEntry(this);
break;
}
}
}
public abstract class InnerLogEntry
{
protected LogEntry Parent;
public InnerLogEntry(LogEntry logEntry)
{
Parent = logEntry;
}
}
public class InformationLogEntry : InnerLogEntry
{
public InformationLogEntry(LogEntry logEntry)
: base(logEntry)
{
//parse custom data
}
}
public class ErrorLogEntry : InnerLogEntry
{
public ErrorLogEntry(LogEntry logEntry)
: base(logEntry)
{
//parse custom data
}
}

Categories