02-13-2017 11:24 AM
Hi,
I am running into below issue. I am working on a Unity WF Script and I have added V4.0 System.Core also. I am getting below error.
The type or namespace name 'Linq' does not exist in the namespace 'System.Xml' (are you missing an a
ssembly reference?)
Any idea how can I solve this error?
Thanks for the help.
Regards
Srinivas
02-13-2017 11:36 AM
Hi Srivinas,
This is an issue in versions earlier than 16. Linq includes static references that are incompatible with the Unity script environment.
Options to fix the problem are:
1. Upgrade to v16, where Linq is supported
2. Convert to a loop or other object that doesnot use Linq
Hope that helps,
-Scott
02-13-2017 12:23 PM
Scott, I don't think what you said is necessarily accurate.
This Unity API blog post talks about what changed in 16:
www.onbase.com/.../linq-in-unity-scripts
It is entirely possible to use LINQ in many ways in earlier versions of OnBase- though for some uses it will be inconvenient. The Unity Script compiler in earlier versions won't let you do things that get compiled as a static anonymous method delegate, and the compiler will tell you something pretty specific (though not necessarily helpful if you don't already know what the problem is).
You can still use a lot of LINQ's power, and you can get around that specific problem by declaring a delegate method in your code instead of using an anonymous function- just at a large expense in brevity in the code.
EDIT: nobody should rely on my exactwording (or even understanding!) of the details too much. E.g. I think "static anonymous method delegate" gets the point across but may not be absolutely precise terminology.
02-13-2017 12:47 PM
02-13-2017 12:52 PM
02-14-2017 05:59 AM
Scott, below are some examples of how you can use LINQ (but it may be more cumbersome than it is worth).
After thinking a little more (mostly about the fact that I don't really know LINQ-To-XML!), you're probably right that Srinivas won't be successful- but his initial compiler error message isn't about the LINQ limitations in Unity Scripts pre-16.
The code below compiles (I threw it in a Global Client Script) on OnBase v15, referencing the System.Core 4.0.0 Assembly and "using System.Collections.Generic", "using System.Linq;".
public void OnGlobalClientScriptExecute(Hyland.Unity.Application app, Hyland.Unity.GlobalClientEventArgs args)
{
//
//String examples of LINQ Where
//
List strings = new List {"ab","bc","cd"};
IEnumerable subset;
IEnumerable upperStrings;
//this won't compile
//error: Unity Event implementations cannot contain static fields: "yyAFLINQTestGood.CS$<>9__CachedAnonymousMethodDelegate6".
//subset = strings.Where(x => x == "ab");
//this won't compile either
//subset = strings.Where(delegate(string s) {return s == "bc";});
//or this
//Func StartsWithC = delegate(string s) {return s.StartsWith("c");};
//subset = strings.Where(StartsWithC);
//or this
//upperStrings = strings.Select(x => x.ToUpper());
//these lambdas will all work
//see methods defined below
subset = strings.Where(x => StartsWithA(x));
subset = strings.Where(x => StartsWith(x, "a"));
subset = strings.Where(x => AreEqual(x,"ab"));
upperStrings = strings.Select (x => MyUpper(x));
//or syntax where we pass a method that meets an expected Func<> signature instead of a lambda
//simpler or more confusing? depends on what you're used to
subset = strings.Where(StartsWithA);
upperStrings = strings.Select(MyUpper);
//
//Examples of other LINQ functions
//LINQ is not just Where!
//Some don't require any special tricks
//some will require adjustments like Where did
//
List numbers = new List {1,2,2,3,4,5};
long max = numbers.Max();
long sum = numbers.Sum();
double average = numbers.Average();
long product = numbers.Aggregate(1L, MyProduct);
IEnumerable distinctNumbers = numbers.Distinct();
}
bool StartsWithA(string s) { return s.StartsWith("A"); }
bool StartsWith(string s, string start) { return s.StartsWith(start); }
bool AreEqual(string a, string b) { return a == b; }
string MyUpper(string s) { return s.ToUpper(); }
long MyProduct(long runningValue, long newInput) { return runningValue * newInput; }
02-14-2017 07:23 AM
Srinivas, I poked around a little more and at least some LINQ-To-XML functionality definitely can be used in a Unity Script with the techniques I described above. This is a bit more cumbersome than LINQ usage often is, so your plan of moving code to a DLL that gets imported may be best for you.
My proof-of-concept adds references to (I'm not sure these are all actually required):
System.Core
System.Xml
System.Xml.Linq
And using statements (again, not sure these are all required):
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
And code:
public void OnSomeKindOfUnityScript(Hyland.Unity.Application app, Hyland.Unity.SomeKindOfEventArgs args)
{
XDocument myDocument = GetWhatever();
//won't compile
//var subsetOfElements - elements.Where(x => (string)x.Attribute("name") == "Bob");
//will compile
var subsetOfElements = elements.Where(x => AttributeEquals(x.Attribute("name"), "Bob");
}
bool AttributeEquals(XAttribute attribute, string s) {return (string)attribute == s;}
XDocument GetWhatever()
{
//...
}
Depending on your needs, you might end up writing a LOT of helper methods like AttributeEquals(), maybe with different overloads.
You could also rewrite that helper as "bool AttributeEquals(XElement element, string attrName, string s)" or some other form that you find most convenient.
Again, moving your code to a DLL for the simplest LINQ usage might still be the most convenient option, but it seems like it is entirely possible to use LINQ-To-XML in pre-16 Unity Scripts with a little extra overhead.
Find what you came for
We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.