Is there any way I can control the formatting of this statement?
var element = new XElement("Element", true);
So that I can get this output, for example:
<Element>True</Element>
I'm looking for a pluggable formatter, not something like true ? "True": "False"
I have tried to go through elements afterwards, but it seems like the constructor of XElement calls ToString() on the value which means I have a hard time evaluating types.
Totally revamped answer:
Previously I recommended XmlWriter, but as it turns out that is not possible.
I'm editing this answer since XElement did not preserve types the way I thought, ie in
var x = new XElement("element", true);
x.WriteTo(new XmlTextWriter(Console.Out)); // Write stuff to console using XmlTextWriter
WriteValue(Boolean) is never called, the value is stored as XText in the XElement.
For those interested, XElement.WriteTo calls XmlWriter.WriteElement (an extension method) which in turn calls XmlWriter.WriteString.
It is possible to change the behavior of XmlWriter.WriteString but that also changes the output of
var x = new XElement("element", "true"); // String instead of bool
since the types are not stored.
My solution would be to create a factory and through it control how XElements are created. IE:
class XElementFactory {
public static XElement CreateXElement(string name, object value) {
var type = obj.GetType();
if (typeof(boolean).Equals(type))
// Format the XText accordig to specification, use the XText ctor for clarification and readability
return new XElement(name, (bool) obj ? new XText("True") : XText("False"));
// Maybe add additional if clauses if there are just a few special cases
return new XElement(name, obj); // Let it through
}
}
The reflection seriously hurts performance, but since we are dealing with XML my guess is that performance is not that important to begin with. If needed use a builder pattern where the correct builder gets called depending on type, ie something along the lines of:
Builders.First(b => b.Types.Contains(objToBuild.GetType())).BuildXElement(objToBuild); // Builders could maybe be filled by MEF?
This answer got kinda long (but I had something do during a long conference call =P), and in essence the issue turned out not to be a formatting problem but a creation problem.
Related
For example I have XElement looks like this:
<Id>5E64F866-823E-4B2F-AE7D-D780444011E9</Id>
And I need to convert it to System.Guid. I know that I can do this using explicit conversion:
var xElem = xElement.Parse("<Id>5E64F866-823E-4B2F-AE7D-D780444011E9</Id>");
var myGuid = (Guid)xElem;
But what I actually need is:
var guidType = typeof(Guid);
var xElem = xElement.Parse("<Id>5E64F866-823E-4B2F-AE7D-D780444011E9</Id>");
var myGuid = xElem.ConvertToObject(guidType); // for example, pseudo method
I use reflection in my code, and I need ability to set value to the property using propertyInfo.SetValue(object, object). The possible types of value I set to the property is always one of the type XElement explicit conversion supports(msdn). Hope someone understand my question:)
Is there a way to do this? Thank you!
The XElement DOM does not support binding attributes or body to a particular type. It'll always be a string.
Assuming what you've provided is just a simplified example though, the below might help you would in a more complex scenario.
IEnumerable<Guid> ids = from e in d.Root.Elements()
where e.Name == (ns + "employee")
select new Guid(e.Attribute("Id").Value);
Or you could design up an extension method to XElement which would see if the passed type has a constructor which takes in a string through reflection and call it. That's a bit more complex though.
I want to pass a property name as an argument:
protected T findControl<T>(string myProperty, string myPropertyValue , UITestControl control = null) where T : UITestControl, new()
{
var uiContainer = control ?? Window;
return uiContainer.SearchFor<T>(new { myProperty = myPropertyValue });
}
public static T SearchFor<T>(
this UITestControl control,
dynamic searchProperties,
dynamic filterProperties = null) where T : UITestControl, new()
I use:
return findControl<HtmlComboBox>("id", "PersonComboBox")
When debuging, I get:
dynamic searchProperties = {myProperty = PersonComboBox}
what, I would like to is:
dynamic searchProperties = {id = PersonComboBox}
Why is that so? Is there a way to fix that?
Agree with Andrew Sun - dynamics is not very popular feature and it's only usage is dealing with COM interop or with special APIs such Newton.Json,MongoConnector (where it's not very popular too - most developers prefer their Dictionary overload).
If you want impress something dynamic in .net - best way use collections and containers that are mostly close to JS object behavior.
Mostly common used classes for this task is - Dictionary<string,object> (almost exactly same thing as JS object) or Dictionary<string,string> (if it's really string only map and no nesting).
If you must provide nesting - you still can use Dictionary<string,object>, but for some scenarios XElement could be better choice.
I not suggest to use Newton.JSON without large reasone because it's addition dependency and is kind of swiss-knife - you will just use 1% of services it provide.
When think that dynamics are good - remember - it's just hack with not efficient implemenation and it cause CSharp dependency for project and overheat with runtime compilation. I and i think many other people not suggest use them instead of very special cases.
I also agree with my previous speakers that using a Dictionary might be an easier solution here, but if you still want to use dynamics here, you could try the following:
protected T findControl<T>(string myProperty, string myPropertyValue, UITestControl control = null) where T : UITestControl, new()
{
var uiContainer = control ?? Window;
// create an expando object here and reference it as dictionary
IDictionary<string, object> searchProperties = new ExpandoObject();
// now add your data to the dictionary
searchProperties.Add(myProperty, myPropertyValue);
// call your method with your newly created expando object,
// in your method, you can now call "searchProperties.id"
// and also your debug view (open the "Dynamic View" item in VS debugger)
// should show a property called "id"
return uiContainer.SearchFor<T>(searchProperties);
}
I would like to make my code convention-based by using Types and keeping things simple, but generics has it's own complexity with it's own learning curve.
I have a bunch of POCOs (Plain Old CLR Objects) in a List that I'd like to iterate through later in the code.
var models = new List<Type>();
models.Add(typeof(Person));
models.Add(typeof(Company));
Would like to cycle through each list item:
models.ForEach(m =>
{
var label = m.FullName;
// var data = JsonConvert.DeserializeObject<List<typeof(m)>>(""); // doesn't work
var data = JsonConvert.DeserializeObject<List<m>>(""); // doesn't work either
...
}
The issue is that the "m" in the Deserialize line isn't working. What would be the best way to pass that through, i.e. making the 'List<m>' a 'List<T>' that we can use?
To use generics, you really need to know the Type (T) at compile time, you don't - you know it at run time. (Caveat: Its possible with reflection, but theres no need to use it when there's an overload as described below)
There is an overload of DeserializeObject which takes a Type rather than use generics. So your code would be
models.ForEach(m =>
{
var label = m.FullName;
var data = JsonConvert.DeserializeObject("",m);
...
}
However, as you've pointed out in comments you actually need a List<T> not a single T. You'll need a little bit of reflection, just to create the right type to pass to the above DeserializeObject call.
var tList = typeof(List<>); // Type of open List
models.ForEach(m =>
{
var label = m.FullName;
var tConvert = = tList.MakeGenericType(m);
var data = JsonConvert.DeserializeObject("",tConvert);
...
}
The answer to your question is above, but the more I look at it the harder it is to see what you can actually do with data. all you'll ever know about data is that it is an object. You cant cast it to anything - you wont know if its a list of Person or a list of Company.
Perhaps this was an overly contrived example you've used for a real-life problem. If not I forsee you're next problem is what to do with data!!
If you don't know the type at compile time you can do this with Reflection. Consider the following code:
models.ForEach(m =>
{
var mi = JsonConvert.GetType()
.GetMethod("DeserializeObject");
var m = mi.MakeGenericMethod(new[] { m });
// you pass [null] for the object because it's a [static] method
// and you don't have to declare [args] if you can express it simply
// but keep in mind that it's simply an object[]
m.Invoke(null, args);
}
Another solution is to call the generic method using reflection (if there isn't any overload that takes the type as parameter)
models.ForEach(m =>
{
MethodInfo method = typeof(JsonConvert).GetMethod("DeserializeObject");
MethodInfo generic = method.MakeGenericMethod(m);
generic.Invoke(null, "");
}
For example, consider a utility class SerializableList:
public class SerializableList : List<ISerializable>
{
public T Add<T>(T item) where T : ISerializable
{
base.Add(item);
return item;
}
public T Add<T>(Func<T> factory) where T : ISerializable
{
var item = factory();
base.Add(item);
return item;
}
}
Usually I'd use it like this:
var serializableList = new SerializableList();
var item1 = serializableList.Add(new Class1());
var item2 = serializableList.Add(new Class2());
I could also have used it via factoring, like this:
var serializableList = new SerializableList();
var item1 = serializableList.Add(() => new Class1());
var item2 = serializableList.Add(() => new Class2());
The second approach appears to be a preferred usage pattern, as I've been lately noticing on SO. Is it really so (and why, if yes) or is it just a matter of taste?
Given your example, the factory method is silly. Unless the callee requires the ability to control the point of instantiation, instantiate multiple instances, or lazy evaluation, it's just useless overhead.
The compiler will not be able to optimize out delegate creation.
To reference the examples of using the factory syntax that you gave in comments on the question. Both examples are trying (albeit poorly) to provide guaranteed cleanup of the instances.
If you consider a using statement:
using (var x = new Something()) { }
The naive implementation would be:
var x = new Something();
try
{
}
finally
{
if ((x != null) && (x is IDisposable))
((IDisposable)x).Dispose();
}
The problem with this code is that it is possible for an exception to occur after the assignment of x, but before the try block is entered. If this happens, x will not be properly disposed, because the finally block will not execute. To deal with this, the code for a using statement will actually be something more like:
Something x = null;
try
{
x = new Something();
}
finally
{
if ((x != null) && (x is IDisposable))
((IDisposable)x).Dispose();
}
Both of the examples that you reference using factory parameters are attempting to deal with this same issue. Passing a factory allows for the instance to be instantiated within the guarded block. Passing the instance directly allows for the possibility of something to go wrong along the way and not have Dispose() called.
In those cases, passing the factory parameter makes sense.
Caching
In the example you have provided it does not make sense as others have pointed out. Instead I will give you another example,
public class MyClass{
public MyClass(string file){
// load a huge file
// do lots of computing...
// then store results...
}
}
private ConcurrentDictionary<string,MyClass> Cache = new ....
public MyClass GetCachedItem(string key){
return Cache.GetOrAdd(key, k => new MyClass(key));
}
In above example, let's say we are loading a big file and we are calculating something and we are interested in end result of that calculation. To speedup my access, when I try to load files through Cache, Cache will return me cached entry if it has it, only when cache does not find the item, it will call the Factory method, and create new instance of MyClass.
So you are reading files many times, but you are only creating instance of class that holds data just once. This pattern is only useful for caching purpose.
But if you are not caching, and every iteration requires to call new operator, then it makes no sense to use factory pattern at all.
Alternate Error Object or Error Logging
For some reason, if creation fails, List can create an error object, for example,
T defaultObject = ....
public T Add<T>(Func<T> factory) where T : ISerializable
{
T item;
try{
item = factory();
}catch(ex){
Log(ex);
item = defaultObject;
}
base.Add(item);
return item;
}
In this example, you can monitor factory if it generates an exception while creating new object, and when that happens, you Log the error, and return something else and keep some default value in list. I don't know what will be practical use of this, but Error Logging sounds better candidate here.
No, there's no general preference of passing the factory instead of the value. However, in very particular situations, you will prefer to pass the factory method instead of the value.
Think about it:
What's the difference between passing the parameter as a value, or
passing it as a factory method (e.g. using Func<T>)?
Answer is simple: order of execution.
In the first case, you need to pass the value, so you must obtain it before calling the target method.
In the second case, you can postpone the value creation/calculation/obtaining till it's needed by the target method.
Why would you want to postpone the value creation/calculation/obtaining? obvious things come to mind:
Processor-intensive or memory-intensive creation of the value, that you want to happen only in case the value is really needed (on-demand). This is Lazy loading then.
If the value creation depends on parameters that are accessible by the target method but not from outside of it. So, you would pass Func<T, T> instead of Func<T>.
The question compares methods with different purposes. The second one should be named CreateAndAdd<T>(Func<T> factory).
So depending what functionality is required, should be used one or another method.
I need to create the ability to drill through an objects properties like two or three deep. For instance, class A has a property reference to class B, which I need to access class C. What is the best way to do this: straight reflection, or maybe using the TypeDescriptor, or something else?
Thanks.
It's not too hard to write. I put a few classes together to deal with this so I could serialize properties of a WinForm. Take a look at this class and the related classes.
http://csharptest.net/browse/src/Library/Reflection/PropertySerializer.cs
If you know the path in a static context (ie the path is always the same) and the properties are accessible (internal or public) you can use dynamic
[Test]
public void Foo()
{
var a = new A
{
B = new B
{
C = new C
{
Name = "hello"
}
}
};
DoReflection(a);
}
private void DoReflection(dynamic value)
{
string message = value.B.C.Name;
Debug.WriteLine(message);
}
I you wanna write you own serialization code for whatever reason, you'll be using reflection.
What you do is that you write a recursive method of serlizating a type. You then apply this as you see fit to get the result.
var type = myObjectOfSomeType.GetType();
// now depending on what you want to store
// I'll save all public properties
var properties = type.GetProperties(); // get all public properties
foreach(var p in properties)
{
var value = p.GetValue(myObjectOfSomeType, null);
Writevalue(p.Name, value);
}
The implementation of WriteValue have to recognize the built in types and treat them accordingly, that's typical things like string, char, integer, double, DateTime etc.
If it encounters a sequence or collection you need to write out many values.
If it encounters a non trivial type you'll apply this recursive pattern again.
The end result is a recursive algorithm that traverses your object model and writes out values as it encounters types that I know how to serialize.
However, I do recommend looking into WCF, not for building services, but for serialization. It shipped as part of the .NET 3.0 framework with a new assembly System.Runtime.Serilization and in general is very capable when dealing with serialization and data annotations.