I have an object (a system GUID) I need to use repeatedly in my class library. I would like to store it somewhere. Whats the best way to do that? Im thinking i could serialize and deserialize the object but it dosent seem like the simplest solution.
Just convert it into a string, store this in your Resources/App.Confing/Whatever (even as a constant in some of your classes) and use the constructor of Guid with the string overload to load it.
Related
TLDR Question:
How to cast a string to a specific type of object?
Long Question
I want to make a PlayerPrefs wrapper where I can store whatever data I want.
so it goes like this
void Set<T>(string Key, T Value)
{
PlayerPrefs.SetString(Key, Value.ToString());
}
T Get<T>(string Key)// where T : IParseable
{
//Code that checks for errors and throws exceptions
return T.Parse(PlayerPrefs.GetString(Key));
}
The problem in this is that it "relies" on the data to be parseable (or implement IParseable that I invented XD) and primitive data types don't implement it even thought they all have a Parse Method
Is there already an IParseable interface I can use?
If not, is there a way to know if the T type is a primitive data type?
Is there a better way to achieve what I want to do?
Would it be better if I used JSON for this?
The comments are correct, you shouldn't be using ToString() and Parse. What you are doing (or trying to do) is serialization. Here are a couple of resources to look to for figuring out how to serialize and deserialize your data:
Serialize an object to string
https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-serialize-and-deserialize-json-data
If you use one of the above examples, the data should be serialized to a human-readable format. It's less efficient, but serializing to a string is already less efficient than serializing to bytes. If you need that level of efficiency, you shouldn't be using PlayerPrefs.
I am working on C# TCP Server-Client programming. My problem is simple but somehow i couldnt figure it out.
I have an object i would like to seriliaze this object send over socket and deserialize client side. But problem is with deserializing. I serialize object with binaryformatter. Actually i am getting the actual byte array i should. But somehow while deserializing i am getting
System.Runtime.Serialization.SerializationException: 'Multi Server,
Version=1.0.0.0, Culture=neutural, PublicTokenKey=Null' assembly could
not found.
When i try to deserialize on the server side after serializing it has no problem.
I tried to customize binder which didnt work also. I really appriciate if somebody could help me.
If I'm guessing correct, you have 2 projects - "Multi Client" and "Multi Server".
You serialize object defined in "Multi Server" and then you have a copy of that class in "Multi Client".
So you serialize an object "MultiServer.SomeClass" and then you want to make it a "MultiClient.SomeClass". This ain't gonna work.
You need to create a common dll project (let's name it "MultiCommon", where you will put your class, and reference it by both "MultiServer" and "MultiClient". In this way, you will serialize and deserialize not "MultiServer.SomeClass" but "MultiCommon.SomeClass".
It sounds like you're using BinaryFormatter, in which case frankly I think the most valuable advice would be: don't do that. The data format of BinaryFormatter is fundamentally tied to your exact implementation details, making it very hard to a: have different code at different ends (meaning: deployment is very hard and brittle - everywhere needs to change at the same time), or b: revise the implementation over time.
Frankly, I would strongly advise looking at alternative serialization tools. I'm hugely biased, but protobuf-net works very well for this type of scenario; it is still "binary" (meaning: not text), but it isn't tied to the internal implementation details. It is fast (usually much faster than BinaryFormatter), efficient (usually much less bandwidth required than BinaryFormatter), free, and is usually very easy to apply to an existing object model; it usually means going from this:
[Serializable]
public class Custom {
public int Id {get;set;}
public string Name {get;set;}
// ...etc
}
to this:
[ProtoContract] // you can keep the [Serializable] for compat if you want
public class Custom {
[ProtoMember(1)]
public int Id {get;set;}
[ProtoMember(2)]
public string Name {get;set;}
// ...etc
}
I´m writing a function which parses JSON and may return different types of objects.
Say, I´m parsing an bird json and want to return a bird object, then a tiger json and want to get a tiger object insted.
How can I do this? Should I use a dynamic object? And, if this is the answer, HOW?
I don´t want to overload the logic on each type of object I´d want to get from it.
Thanks in advance,
Ariel
Are you using JSON.NET? Generics seem to be the right answer, at any rate. Something like this:
public T CreateAnimal<T>(string json) {
return JsonConvert.DeserializeObject<T>(json);
}
Note that in order to use this, you would have to know ahead of time which type of object you would expect in the json, so you can call it like this:
Tiger t = CreateAnimal<Tiger>(tigerJson);
To prevent bloated code, you could instantiate your animal objects convention-based:
Activator.CreateInstance("YourAssemblyNameContainingAnimalTypes", animalString);
I have a class:
public class SomeClass {
// properties and methods here
}
Ideally I'd like to send the entire class to a string so I can render it in a view. The best way I can think of doing this, is to have a build script run and send it all to static text files, then reference those text files in the code. Is there a better way to do this? I'd like to be able to say:
return View(SomeClass.SourceToString());
I'm hoping I'm not missing a really obvious way to accomplish this.
C# is compiled into MSIL. There is no direct way to access the original source other than referencing the original source file.
You could use reflection to enumerate all the members of the class and emit each member's declaration/definition to a StringBuilder, and then return the built string.
I'm afraid there is nothing straightforward, and the reflection will give you a "reinterpreted" form of the code, with different structure, no comments, no body for methods...
Maybe you could save a "copy" of your code using a post-build script and resolve it when the SourceToString method is called.
I think you should really explain why you would a such like thing ? Maybe we will be able to suggest you a better solution.
Is it somehow possible to use the XmlSerializer to deserialize its data into an existing instance of a class rather than into a new one?
This would be helpful in two cases:
Easily merge two XML files into one object instance.
Let object constructer itself be the one who is loading its data from the XML file.
If the is not possible by default it should work by using reflection (copying each property after the deserialisation) but this would be an ugly solution.
Basically, you can't. XmlSerializer is strictly constructive. The only interesting thing you can do to customize XmlSerializer is to implement IXmlSerializable and do everything yourself - not an attractive option (and it will still create new instances with the default constructor, etc).
Is xml a strict requirement? If you can use a different format, protobuf-net supports merging fragments into existing instances, as simply as:
Serializer.Merge(source, obj);
I think you're on the right track with the Reflection idea.
Since you probably have a wrapper around the XML operations anyway, you could take in the destination object, do the deserialization normally into a new object, then do something similar to cloning by copying over one by one only the properties holding non-default values.
It shouldn't be that complex to implement this, and it would look to consumers from the rest of your application just like in-place deserialization.
I hit the same problem a few weeks ago.
I put a method Deserialize(string serialized form) in the ISelfSerializable interface that an entity class of mine implemented. I also made sure the interface forced the class to have a default constructor.
In my factory I created an object of that type and then deserialized the string into it.
This is not thread safe thing to do... But you can do:
[Serializable]
public class c_Settings
{
static c_Settings Default;
public static SetExistingObject(c_Settings def)
{
Default = def;
}
public string Prop1;
public bool Prop2;
public c_Settings()
{
if (Default == null)
return;
MemberInfo[] members = FormatterServices.GetSerializableMembers(typeof(c_Settings));
FormatterServices.PopulateObjectMembers(this, members, FormatterServices.GetObjectData(Default, members));
}
}
This way you feed your object to deserialiser and deserialiser only overwrites whatever is written in .xml.