1

I have an custom class DataLookupList, and it has the following private member

private Func<TValue, TKey> m_selector;

I want to be able to export its state to XML ( XML is a requirement, so I can't use binary or something else ), so I can import the object in another place. I can't seem to be able to export the Func<> to a String though. When exporting it to XML via

new XElement( "Selector", m_selector )

I get its string representation which is "System.Func`2[System.Int32,System.Int32]", but when I try to import it via

TypeDescriptor.GetConverter( typeof( Func<TValue, TKey> ) ).ConvertFromString( element.Value )

I get an error, because "System.Func`2[System.Int32,System.Int32]" cannot be parsed back.

Is it possible at all to store a Func to a String, and if not why ?

  • 1
    If changing to `Expression>` is an option, look at [Serializing and Deserializing Expression Trees in C#](http://stackoverflow.com/questions/217961/serializing-and-deserializing-expression-trees-in-c-sharp) – Tim S. Nov 18 '13 at 15:24
  • No, there is no hope to export a `Func` to XML. You could _try_ to export a `Expression>`, but it wouldn't be easy (it wouldn't be automatic, you'd have to write code for it or try to find an existing open source library to do it). – Kris Vandermotten Nov 18 '13 at 15:25
  • From quick reference it looks like Serializing Expression Trees is not a trivial task. Any ideas why Func<> cannot be expressed as a string? – Vladimir Vasilev Nov 18 '13 at 15:34
  • A class needs a parameterless constructor to be serializable. `Func<>` does not have a parameterless constructor – Moho Nov 18 '13 at 15:35
  • 1
    Think of a `Func<>` as a compiled function (like the IL code produced by the C# compiler), not uncompiled code (like C# code). While it's possible to decompile the function, it's a lot easier to de/serialize the uncompiled code and then compile it when you need to. Even working with `Expression<>`s in that way is fairly difficult, unfortunately, as they weren't really designed to be serialized and deserialized. – Tim S. Nov 18 '13 at 15:37
  • 2
    As an example of why this is more difficult than it seems, suppose you have a `Func<>` that came from a lambda that reads and modifies local variables from the method it was declared in: such a thing can't be serialized and deserialized, because it works with the state of the method on the machine and thread that started it. – Tim S. Nov 18 '13 at 15:40
  • Thanks @TimS. that makes it clearer. Guess I'll just dump the current design of the class and the Func<> and think of a better way to serialize it. If you find the time, please summarize your comments so I can mark it as an answer – Vladimir Vasilev Nov 18 '13 at 15:43

1 Answers1

2

If changing to Expression<Func<TValue, TKey>> is an option, look at Serializing and Deserializing Expression Trees in C#

Think of a Func<> as a compiled function (like the IL code produced by the C# compiler), not uncompiled code (like C# code). A Func<> cannot always be serialized and deserialized. For example, the following Func<string> comes from a lambda, and reads and modifies the i variable running in this method on this thread on this computer. If I serialized this Func and then deserialized it on another computer, what i should it read and write?

void SomeMethod()
{
    int i = 0;
    Func<string> inc = () => (i++).ToString();
    inc();
    inc();
    Console.WriteLine(i); // 2
}
Community
  • 1
  • 1
Tim S.
  • 55,448
  • 7
  • 96
  • 122