The non-generic version of CastRangeAndAdd works fine. If I skip the (object)
var castedList = list.Select(e => (NewType)e).ToList();
then there is a compile error. If I use the (object) then there is an exception "type TypeHintExcel can not be converted to TypeHint" though the cast operator is there. Any idea? (TypeHint and TypeHintExcel are not related so as I understand the "as keyword" can not be used.)
public static explicit operator TypeHint(TypeHintExcel p)
{
var result = new TypeHint()
{
Id = p.Id,
Hint = p.Hint,
ExternalType = p.ExternalType,
AlienType = p.AlienType,
Weight = p.Weight
};
return result;
}
public static class DbSetExtensions
{
public static void CastRangeAndAdd<OldType, NewType>
(this System.Data.Entity.DbSet<NewType> dbCollection,
List<OldType> list)
where NewType : class
{
var castedList = list.Select(e => (NewType)(object)e).ToList();
dbCollection.AddRange(castedList);
}
}
You can't write a generic method to do this. The explicit conversion operation needs to be bound at compile time, but when that method is compiled it has no idea what the source and destination types are, so it can't possibly be bound to your custom conversion operator.
c# is not as flexible as c++
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/differences-between-cpp-templates-and-csharp-generics
C++ allows code that might not be valid for all type parameters in the template, which is then checked for the specific type used as the type parameter. C# requires code in a class to be written in such a way that it will work with any type that satisfies the constraints. For example, in C++ it is possible to write a function that uses the arithmetic operators + and - on objects of the type parameter, which will produce an error at the time of instantiation of the template with a type that does not support these operators. C# disallows this; the only language constructs allowed are those that can be deduced from the constraints.
Related
I have two interfaces
public interface ISerializableDictionary { ... }
public interface ISerializableDictionary<TKey,TValue>
: ISerializableDictionary { ... }
I need to cast from the former to the latter at run time using reflection.
It's clearly easy to interrogate the former with GetType().GetGenericArguments.
But how do I then do the cast? I have this code below but it is failing to compile, for the obvious reason that I am trying to use a variable as a type.
Type[] genericTypes = dictionary.GetType().GenericTypeArguments;
Type keyType = genericTypes[0];
Type valueType = genericTypes[1];
// this compiles but doesn't do the cast
Type dictType = typeof(SerializableDictionary<,>).MakeGenericType(keyType, valueType);
var createdDictionary = Activator.CreateInstance(dictType);
// this is the line that won't compile - 'dictionary' is a SerializableDictionary, and I want to access it through its typed generic interface
ISerializableDictionary<keyType,valueType> serializableDictionary = dictionary as ISerializableDictionary<keyType, valueType>;
The more specified interface has a method which I need to call. The less specified interface does not (and can't ever be, because the call needs a typed argument).
Is the solution something to do with dictionary.GetType().GetInterfaces()?
Any steer will be wildly appreciated. Programming solo at the moment so I don't have a team to call on, hence the query here.
UPDATE - in response to comments
The problem I am trying to solve is how to serialize members of an object where the members are themselves enumerable. I am trying to figure out how serialization libraries do it as a learning exercise and because I have a few ideas that I want to explore. Serialization & Reflection are not my main areas of programming so I am stumbling to learn them.
So I have (as reduced code):
public class ExperimentalSerializer<T>
{
public void Serialize(T objectToSerialize)
{
IEnumerable<object> collectionsToSerializeToCSV = objectToSerialize.GetEnumerableMembers();
foreach (object collectionToSerialize in collectionsToSerializeToCSV)
{
string csvString = "";
if (collectionToSerialize.IsDictionary())
{
// serialize dictionary here to csvString
// but cannot properly access contents through just IDictionary
// need IDictionary<TKey,TValue>
// ** ALSO SEE TEXT BELOW THIS CODE SNIPPET**
}
else if (collectionToSerialize.IsList())
{
// serialize list here to csvString
}
else if (collectionToSerialize.GetType().IsArray)
{
// serialize array here to csvString
}
// save csvString to somewhere useful here
}
}
}
And elsewhere I have an extension method:
public static IEnumerable<object> GetEnumerableMembers(this object objectToInterrogate)
{
Type objectType = objectToInterrogate.GetType();
// get the enumerable properties
PropertyInfo[] properties = objectType.GetProperties(BindingFlags.Instance | BindingFlags.Public);
IEnumerable<PropertyInfo> enumerableProperties = properties.Where(propertInfo => propertInfo.PropertyType.GetInterfaces().Any(x => x == typeof(IEnumerable)));
IEnumerable<PropertyInfo> serializableProperties = enumerableProperties.Where(p => p.IsSerializable());
IEnumerable<object> enumerablePropertyValues = serializableProperties.Select(p => p.GetValue(objectToInterrogate, null));
// get the enumerable fields
FieldInfo[] fields = objectType.GetFields(BindingFlags.Instance | BindingFlags.Public);
IEnumerable<FieldInfo> enumerablefields = fields.Where(propertInfo => propertInfo.FieldType.GetInterfaces().Any(x => x == typeof(IEnumerable)));
IEnumerable<object> enumerablefieldValues = enumerablefields.Select(f => f.GetValue(objectToInterrogate));
// merge the two lists together
IEnumerable<object> enumerableMembers = enumerablePropertyValues.Union(enumerablefieldValues);
return enumerableMembers.ToList();
}
One specific challenge I am investigating is how to serialize an enumerable (Dictionary, List or array TValue[]) where TValue is itself a complex type (e.g. a class that can be serialized). This cannot be ascertained without knowing the type of TValue, but this cannot be retrieved from IDictionary or IList alone and these can only be enumerated with the type object.
This is the very specific point I am trying to investigate and potentially to control: how to determine TValue and then to work out if/how to serialize it in turn. My idea is to cast to more-specified generics with known type parameters but I get a bit lost at this point.
Hope this helps.
#SLaks points out in the comments:
Casting is inherently a compile-time operation. Casting to a type only known at runtime makes no sense. You can't call your method if its types are not known at compile-time.
That's absolutely right. You can, of course, still call the intended method at runtime, but you'll need to use (more) reflection to do it, since you have no way to get the compiler to generate a statically-typed call.
To do this, take the Type object you already constructed using MakeGenericType(), and call GetMethod() on it to get the Type.MethodInfo object corresponding to the method to call. Then, call MethodInfo.Invoke().
Type dictType = typeof(SerializableDictionary<,>).MakeGenericType(keyType, valueType);
MethodInfo method = dictType.GetMethod("MyMethod");
object returnValue = method.Invoke(dictionary, new object[] { /* arguments */ });
TMI...
When you write dictionary.MyMethod(), the C# compiler generates a Callvirt IL (byte code) instruction. The object to call the method on (and the arguments to the method) are pushed onto the stack, and the argument to Callvirt is the metadata token corresponding to the type-qualified ISerializableDictionary<TKey,TValue>.MyMethod method. This is the normal calling mechanism in .NET. When you (and the compiler) don't know what TKey and TValue are at compile time, there's no way to get the right metadata token for the method, and no way to generate the Callvirt. That's why you have to use the reflection API.
You can, however, use something like DynamicMethod to generate your own IL and JIT it at runtime. Once JITted, the call is just as fast as one statically generated by the compiler. There is of course significant overhead to generating a dynamic method, but it's a one-time overhead.
Of course, #DavidL points out:
The approach here seems wildly off-course. Instead of asking for a specific solution, can you please describe the specific concrete problem that you are trying to solve?
That, too, is absolutely right. So don't do what I just suggested unless you really, really know what you're doing and have a really, really good reason. (Hint: You don't.) But I thought this information might give you a better overall picture of why you can't do what you expected to do.
I regularly find myself coding things like
int? min = someQueryable
.Where(x => someCondition)
.Select(x => (int?)x.someNonNullableIntProperty)
.Min();
It allows me to get null instead of "System.ArgumentNullException: value cannot be null" when nothing matches the condition. (And I do not want to get 0 instead of null.)
I would like to avoid the cast. Is there any other way I have missed?
The hard part is, it should be of sufficiently common use to be natively understood (or ignored) by linq providers. (linq-to-entities and linq-to-nhibernate for my specific needs.)
Otherwise I would have to add some custom AsNullable extensions to linq-to-nh provider (which requires some work), and I do not know if EF (6) allows to do this.
Why do I wish avoiding cast? Casting may go unnoticed during refactoring, and then may cause bugs. And most of the cast I see in code are due to careless developers, not trying to memorize they can have the non-null value from .Value on nullable types, by example. (There is also the ternary case like someCondition ? someIntProperty : (int?)null but the "Elvis" operator ?. will probably allow to avoid most of them ; and we can also write default(int?), althougth it is a bit lengthy. ?. could maybe even be used for my example query, but it would not be a general solution.)
Trying new Nullable<int>(x.someNonNullableIntProperty) as suggested here fails with a NotSupportedException (with NH, not tested with EF). Anyway, it would not suit me either. In case of some later type change of the property, it may go unnoticed too due to implicit conversion. (And trying new Nullable(x.someNonNullableIntProperty) does not compile, generic type argument inferring does not work well with constructors.)
Trying x.someNonNullableIntProperty as int? (which is still a cast, but less tolerant about types mismatch in this case, see this here) fails with an ArgumentException (NH tested again, Expression of type 'System.Int32' cannot be used as a 'System.Nullable`1[System.Int32]' return type (translated)).
I tried this once, but for IEnumerable, and came up with
public static T? max<T>(IEnumerable<T> values) where T: struct, IComparable<T>
{
T? result = null;
foreach (var v in values)
if (!result.HasValue || (v.CompareTo(result.Value) > 0))
result = v;
return result;
}
To handle IQueryable, you'd need to extend your data access library. In case of NHibernate, the mechanism is called HqlGenerator. See this answer for links.
For Entity Framework, I have given up. It looks as too much effort for me. (See here.)
For NHibernate, I have done the AsNullable extension I was thinking of.
This is following the same logic as my other extensions here and here.
First, define an AsNullable extension:
public static class NullableExtensions
{
public static T? AsNullable<T>(this T value) where T : struct
{
// Allow runtime use.
// Not useful for linq-to-nhibernate, could be:
// throw NotSupportedException();
return value;
}
}
Then, implements its HQL translation (originally based on NHibernate compare implementation, then quite simplified, see edits):
public class AsNullableGenerator : BaseHqlGeneratorForMethod
{
public AsNullableGenerator()
{
SupportedMethods = new[]
{
ReflectionHelper.GetMethodDefinition(() => NullableExtensions.AsNullable(0))
};
}
public override HqlTreeNode BuildHql(MethodInfo method,
Expression targetObject,
ReadOnlyCollection<Expression> arguments,
HqlTreeBuilder treeBuilder,
IHqlExpressionVisitor visitor)
{
// Just have to transmit the argument "as is", HQL does not need a specific call
// for null conversion.
return visitor.Visit(arguments[0]).AsExpression();
}
}
Extend the default linq2NH registry with your generator:
public class ExtendedLinqToHqlGeneratorsRegistry :
DefaultLinqToHqlGeneratorsRegistry
{
public ExtendedLinqToHqlGeneratorsRegistry()
: base()
{
this.Merge(new AsNullableGenerator());
}
}
Now configure NH to use your new registry. With hibernate.cfg.xml, add following property node under session-factory node:
<property name="linqtohql.generatorsregistry">YourNameSpace.ExtendedLinqToHqlGeneratorsRegistry, YourAssemblyName</property>
Or using code:
using NHibernate.Cfg;
// ...
var cfg = new Configuration();
cfg.LinqToHqlGeneratorsRegistry<ExtendedLinqToHqlGeneratorsRegistry>();
// And build the session factory using this configuration.
Now we can rewrite the query.
int? min = someQueryable
.Where(x => someCondition)
.Select(x => x.someNonNullableIntProperty.AsNullable())
.Min();
I am sure the answer to this is quite simple but I am trying to write an if statement (C# 5.0) to determine whether or not an anonymous type is empty or not. Here is a simplified version of my code:
public void DoSomething(object attributes)
{
// This is the line I need??
if (atrributes != new {}) {
}
}
The attributes variable gets created dynamically depending on what is needed and sometimes it is empty.
So how do I determine if an anonymous type is empty?
Anonymous types do not provide operator overloads for ==, although it wouldn't matter in this case since one of the arguments is typed object. However the C# compiler does provide Equals, GetHashCode, and ToString implementations.
Use the static object.Equals, method which will do the appropriate null checks and then call the virtual Equals method on the first argument:
object.Equals(attributes, new { });
You could also cache a static instance if you were concerned about the overhead of an allocation for each comparison.
If by empty you mean no properties, you can use reflection:
var o1 = new {};
o1.GetType().GetProperties().Count(); //==0
var o2 = new {test=1};
o2.GetType().GetProperties().Count(); //==1
The code below is valid:
IEnumerable<SomeThing> things = ...;
// map type SomeThing to a new anonymous type, resulting in a strongly typed
// sequence based on an anon type
var newList = things.Select(item =>
{
return new
{
ID = item.ID,
DateUpdatedOrCreated = ((DateTime)(item.DateUpdated ??
item.DateCreated)).ToShortDateString(),
Total = item.Part1 + item.Part2
};
});
newList now appears in Visual Studio as IEnumerable<'a> and is strongly typed with the anonymous type created in the function. That is so cool.
What I can't seem to do is figure out a way to assign just the lambda expression (and not the enumeration) to an implicitly typed variable. Even though the compiler has no problem with the anonymous type in the context above, if I try (say)
var func = (SomeThing item)=> {
return new { ... };
};
I get the error "Cannot assign lambda expression to implicitly-typed local variable". This seems a strange compiler limitation; unless I am missing something, the types are just as non-ambiguous in the 2nd example as they are in the first first: both type parameters are well defined.
Is there any way to do this? Since it's an anonymous type, of course, I don't have any way to use a type to assign it explicitly, so it seems I'd be stuck with making a class for the output type if not.
Update
Shortly after going about my merry way with Jon Skeet's answer, I found a similar dilemma instantiating classes. In case it's not obvious, the same trick can be used to create strongly typed classes using inferred anonymous types.
class Processor<T,U>
{
public Processor(Func<T,U> func) {
}
}
// func is a delegate with anon return type created using method in answer below
var instance = new Processor(func); // does not compile! Requires type arguments!
cannot be created directly, but can be created in much the same way as the trick below:
public static Processor<T,U> Create<T,U>(Func<T,U> func) {
return new Processor<T,U>(func);
}
var instance = Processor.Create(func); // all good
You can do it via type inference:
var func = BuildFunc((SomeThing item) => {
return new { ... };
});
...
static Func<TSource, TResult> BuildFunc<TSource, TResult>(
Func<TSource, TResult> function) {
return function;
}
Note that BuildFunc doesn't really do anything - it just provides the method call needed to get the compiler to do type inference for the generic type arguments for Func<,> - it adds the information that you're interested in Func<,>, basically - that's information which can't be specified as part of a variable declaration, without also specifying the type arguments.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
LINQ to SQL: Return anonymous type?
Do any one know how to return an anonymous type. I am using Linq where i need to return the following code
private <What's the return type to be provided here> SampleLinq(Int32 Num)
{
var query = (from dept in obj.DeptTable where dept.Id == Num select new { dept.DeptName, dept.DeptId });
return (query)
}
Sorry to say but you cannot return anonymous type out side the scope of method.
This is the alternate way to get anonmous type
// Method that returns anonymous type as object
object ReturnAnonymous()
{
return new { City="Prague", Name="Tomas" };
}
// Application entry-point
void Main()
{
// Get instance of anonymous type with 'City' and 'Name' properties
object o = ReturnAnonymous();
// This call to 'Cast' method converts first parameter (object) to the
// same type as the type of second parameter - which is in this case
// anonymous type with 'City' and 'Name' properties
var typed = Cast(o, new { City="", Name="" });
Console.WriteLine("Name={0}, City={1}", typed.Name, typed.City);
}
// Cast method - thanks to type inference when calling methods it
// is possible to cast object to type without knowing the type name
T Cast<T>(object obj, T type)
{
return (T)obj;
}
you can use it only for types in one assembly (two anonymous types from two different assemblies will be internally compiled to two different types that can't be converted using this trick).
Return Dynamic type:
public static dynamic getCustomer()
{
.....
var x = from c in customers
select new {Fname = c.FirstName};
return x;
}
static void Main(string[] args)
{
dynamic x = getCustomer();
Console.WriteLine(Enumerable.First(x).Fname);
Console.ReadKey();
}
you can't do that. that is why it is called anonymous. It doesn't have a name. But you always can cast it to object
Well, you can't actually do that, but here's a hack on this.
private object SampleLinq(Int32 Num)
{
return (from dept in obj.DeptTable where dept.Id == Num select new { dept.DeptName, dept.DeptId });
}
You can't return an Anonymous Type from a method.
You can create a simple Class to wrap the Anonymous Type, but you still need a Class (or cast to object).
Keep in mind, though, that if you cast to object there's no way to cast back. You'll need reflection to read any data.
The answers you see from the hack is a lot of work just to get an anonymous type through a method boundary. You shouldn't be doing this. If you need to pass something back from a method, you should be passing concrete types.
It depends what you looking to do with the return vale.
If your going to bind it in the UI
you can just rerun
IEnumerable or IQueryable.
If your going to use reflection on the return value just return type object
If your using c# 4.0 you can return a
dynamic type
If your using EF or Linq to SQL to further join a query comprised of your anonymous type you
can make a concrete class instead and
use the concrete placeholder
technique. For more details on this
technique I can give some assistance.
As others have mentioned though, you should really question whether returning an anonymous type form a method is the best way to solve the problem at hand. In general there is usually a better more pattern based approach that may require a bit more coding up front but may resulting in a more elegant design. This being said, I do believe there are legitimate cases such as with data binding where returning anonymous type instances can be perfectly acceptable.
UPDATE:
Just an interested tidbit I wanted to share in case those reading are not aware. Anonymous types are unique per their property names and types so lets say you have method A and method B in in both you create an anonymous type that has a single string typed property called Name by doing something like be code below.
public object A()
{
return new { Name = "Cid" }
}
public object B()
{
return new { Name = "Galuf" }
}
public void Test()
{
System.Diagnostics.Trace.Assert(A().GetType() == B().GetType());
}
Now even though this type is defined in two separate places the compiler only creates only creates a single shared type because they both have the same set of properties as defined by the property types and property names. In this respect the properties can be thought of as sort of a signature for the anonymous type. Using this knowledge there are different techniques that can be used for introspection into anonymous type instances that have been cast to object or deferred using the dynamic keyword. There are also nifty ways to work with anonymous types by using generic methods just as Linq does with methods in the static Enumerable and Queryable classes. This way you can do things like create a new instance of any given anonymous type and without using reflection. The trick is though that you have to use an instance of the anonymous type to pass to methods in order to have the type be inferred by the generic method. If anybody is interested in these topics further as they apply to the original posters question, leave a comment and I can try to clarify some of these techniques.