Anonymous type scoping issue - c#

What is the proper way to create a variable that will house a list of anonymous objects that are generated through a LINQ query while keeping the variable declaration outside of a try/catch and the assignment being handled inside of a try/catch?
At the moment I'm declaring the variable as IEnumberable<object>, but this causes some issues down the road when I'm trying to use it later...
i.e.
var variableDeclaration;
try{
...
assignment
...
}catch...
EDIT:
If it's relevant (don't think it is) the list of objects is being returned as a Json result from an MVC3 action. I'm trying to reduce the time that some using statements are open with the DB as I'm having some performance issues that I'm trying to clear up a bit. In doing some of my testing I came across this issue and can't seem to find info on it.
EDIT 2:
If I could request the avoidance of focusing on LINQ. While LINQ is used the question is more specific to the scoping issues associated with Anonymous objects. Not the fact that LINQ is used (in this case) to generate them.
Also, a couple of answers have mentioned the use of dynamic while this will compile it doesn't allow for the usages that I'm needing later on the method. If what I'm wanting to do isn't possible then at the moment the answer appears to be to create a new class with the definition that I'm needing and to use that.

It's possible to get around this by creating a generic Cast method as outlined by Jon Skeet here. It will work and give you the intellisense you want. But, at this point, what's wrong with creating a custom type for your linq method?
public class MyClass
{
public int MyInt { get; set; }
}
IEnumerable<MyClass> myClass =
//Some Linq query that returns a collection of MyClass

Well, if you're using LINQ, the query is not evaluated unless materialized...
So, you might be able to:
var myQuery = //blah
try
{
myQuery = myQuery.ToList(); //or other materializing call
}
catch
{
}

Could you perhaps get away with using dynamic ??
dynamic variableDeclaration;
try
{
variableDeclaration = SomeList.Where(This => This == That);
}
catch { }
Not sure what this will affect further in your code block, but just a thought :)

If you are declaring the variable ahead of using it like a try/catch you can't use [var] as it is intendend. Instead you have to type the the variable.
var x = 0;
try{
x = SomethingReturningAnInt();
}
or
int x;
try{
x = SomethingReturningAnInt();
}
However in your case you don't really "know" what the method returns
var x = ...;
try{
x = Something();
}
catch{}
won't work
Option you have when you don't know the type in advance is use of dynamic:
dynamic x;
try{
x = Something();
}
catch{}
(But that feels like going back to VB4)

Another cheat: you can define variable locally (similarly to Jon's hack in Dave Zych answer) and than use it inside try/catch. As long as you can create the same anonymous item type before try-catch you are OK (as anonymous types wit the same field names and types are considered the same):
var myAnonymouslyType = Enumerable.Repeat(
new {Field1 = (int)1, Field2 = (string)"fake"}, 0);
try
{
myAnonymouslyType = ...(item =>
new {Field1 = item.Id, Field2=item.Text})...
}
...
This is safer option than covered in Jon's casting of anonymous types between functions because compiler will immediately find errors if types don't match.
Note: I'd vote for non-anonymous type if you have to go this way...
Note 2: depending on your actual need consider simply returning data from inside try/catch and having second return of default information outside.

This has vexed me for a while. In the end I've build some Generic helper methods where I can pass in the code that generates the anonymous objects, and the catch code as lamdas as follows
public static class TryCatch
{
public static T Expression<T>(Func<T> lamda, Action<Exception> onException)
{
try
{
return lamda();
}
catch(Exception e)
{
onException(e);
return default(T);
}
}
}
//and example
Exception throwexception = null;
var results = TryCatch.Expression(
//TRY
() =>
{
//simulate exception happening sometimes.
if (new Random().Next(3) == 2)
{
throw new Exception("test this");
}
//return an anonymous object
return new { a = 1, b = 2 };
} ,
//CATCH
(e) => { throwexception = e;
//retrow if you wish
//throw e;
}
);
https://gist.github.com/klumsy/6287279

Related

Convert loop to Maybe monad

Recently I tried applying Maybe monad pattern in my C# code using this library.
What I found difficult to grasp was converting such a function into Maybe paradigm:
public Maybe<object> DoSomething(IReader reader)
{
while (true)
{
var result = reader.Read();
if (result == null) return Maybe<object>.Nothing;
if (result.HasValue) return new Maybe<object>(null);
}
}
I would like to have it written using from x in X form. The functionality that stands behind this function is to read IReader until it returns a value (Maybe has a value) or an error occurs (null gets returned).
the answer to your comment/question is: you don't - yeah you could try it using recursive calls but this might fail horrible in C# and you are way better of with the while
from x in X is just the monadic - bind (it get's translated into the SelectMany functions) and there is just no direct way in the LINQ syntax for this.
But you can write your own function like this:
public tValue DoUntilSome<tValue>(Func<Maybe<tValue>> f)
{
while (true)
{
var x = f();
if (x.HasValue) return x.Value;
}
}
and call like (see below)
var result = DoUntilSome(() => TryRead(reader));
remarks
first the Maybe<object> (object) part is a smell - because you most certainly want a concrete type in there instead of the generic object
Then new Maybe<object>(null) is very strange too
I would have suggested something like:
public Maybe<tValue> TryRead<tValue>(IReader reader)
{
var result = reader.Read();
if (result == null || !result.HasValue)
return Maybe<tValue>.Nothing;
return new Maybe<tValue>((tValue)reader.Value);
}
then of course this part is there to get some Maybe value - the thing you are trying to do with from x in X is the monadic-bind - which you can only use once you have a Maybe to start with:
from value in TryRead<tValue>(reader)
from other in TrySomethingDifferent(value) // here is the bind
select ....
disclaimer
I did not compile any of this (because I was to lazy to download the github project and stuff) - put you should be able to easily solve any syntax errors that might hide there - sorry for that
In case you have major troubles just leave a comment

Detecting closures with cecil

I have code to detect when an exception is created inside of a method like so:
foreach (var instr in body.Instructions)
{
if (instr.OpCode.Code == Code.Newobj)
{
var methRef = (Mono.Cecil.MethodReference)instr.Operand;
var type = Type.GetType(methRef.DeclaringType.FullName);
if (typeof(System.Exception).IsAssignableFrom(type))
// do stuff
}
}
full code here.
So far this is working well for straight forward code, but in the case where I'm dealing with a closure it obviously won't work because the exception is inside of a method on the object generated for the closure, not in the method that I am currently testing. The exception in:
private static int DataAccessMethod(int value)
{
int r = 0;
System.Threading.ManualResetEvent evt = new System.Threading.ManualResetEvent(false);
var workItem = System.Threading.ThreadPool.QueueUserWorkItem((_) =>
{
if (r == 0)
{
throw new System.InvalidOperationException("I canr spell.");
}
r = value * value;
evt.Set();
});
evt.WaitOne();
return r;
}
for instance will go undetected. My question is:
Is there anyway to detect that the operand to newobj is referring to a closure type?
As #usr noted in comments closures are just normal classes, they doesn't exist distinctly in IL. Only difference is you've not created it; compiler did it for you.
I believe you should be looking at unique compiler generated names to find them. EricLippert describes naming conventions followed by compiler here, Do note that it is subject to change in future versions of compiler.
Also after coming to the conclusion that the Type is a closure you can verify that using CompilerGenerated attribute.

Creating an object via lambda factory vs direct "new Type()" syntax

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.

update generic entity in linq to object

I have a function written in linq to sql
public static bool update(System.Linq.Expressions.Expression<Func<T,bool>> predicate,Action<T> setter)
{
try
{
Context myContext = new Context ();
T updateObject;
updateObject = myContext.GetTable<T>().Where(predicate).First();
setter(updateObject);
nhagoDb.SubmitChanges();
return true;
}
catch (Exception ex)
{
return false;
}
}
but i dont know how to write this in linq to object, especially there's no method like GetTable<T>().Where(predicate).First();
please help
many thanks :)
I don't see that such a method is even necessary in LINQ to objects. Your code can simply do the work itself. E.g.
var myObject = myList.First(x => x.Something);
myObject.UpdateSomething(newValue);
// or just:
myList.First(x => x.Something).UpdateSomething(newValue);
If you did want a method to do this, it would be called like:
myList.Update(x => x.Something, x => x.UpdateSomething(newValue));
The former is shorter, clearer (IMO), and faster than the latter.
You can implement myContext.GetTable() yourself. Create an extension method for Context class.
Inside the method use reflection to find the db set whith type T and return it, the rest of your code will work

How to cast list to enumerable

I've got a problem with the following code:
public IEnumerable<ISession> GetSessions()
{
// ...
using (ProvaDbEntities DBEntities = new ProvaDbEntities(Utilities.ToEntitiesConnectionString()))
{
ObjectQuery<session> sessions = DBEntities.session;
IEnumerable<session> q1 = from session in sessions
where session.site == this.Name
select session;
List<Session> sessionList = new List<Session>();
foreach (var s in q1)
{
sessionList.Add(new Session(s.id.ToString(),s.username, s.site, new DateTime()));
}
IEnumerable<Session> res = sessionList;
return sessionList;
}
}
The exception is:
Is not possible to cast object type 'System.Collections.Generic.List`1[prova3.Session]' to type 'System.Collections.Generic.IEnumerable`1[TAP2009.AuctionSite.Interfaces.ISession]'.
Looking at this SO question it seems to be correct. Am I wrong?
It should be fine, so long as Session implements ISession - if you're using C# 4 and .NET 4. If you're not, it won't be.
Note that the question you referred to use the same "T" in both cases - whereas the exception you've got is about converting a List<Session> to an IEnumerable<ISession>. You haven't stated where you're getting the exception, which makes it a bit harder to see exactly what's going on... Are you sure this is actually the code which is failing? Are you sure you're getting an exception rather than a compile-time failure?
EDIT: If you're not using .NET 4 and C# 4, the workaround for covariance is reasonably simple here - use the Cast<T>() LINQ operator:
return sessionList.Cast<ISession>();
Have you tried using the extension method AsEnumerable()?
So this line
IEnumerable<Session> res = sessionList;
Would change to
IEnumerable<Session> res = sessionList.AsEnumerable();
The return type is public IEnumerable<ISession>, i forgot to specify the type of the Ienumerable..
You can add using System.Linq and use the extension method Cast<T> that returns a IEnumerable<T>.

Categories

Resources