Reimplementing Dictionary<string, dynamic> - c#

I want to implement a class that behaves similarly to a Dictionary<string, dynamic>, because the dynamic keyword is causing a weird exception caused by CAS issues which I cannot resolve somewhere else on the project. Basically I want a dictionary that allows getting and setting heterogeneous values without explicit casting.
My attempt has been to get an internal Dictionary<string, Tuple<Type, object>> with the intention of casting it correctly. I would like to overload the square-bracket operator for getting and setting. However, I cannot figure out the correct syntax to do this. I would like to do something like this:
class DynDictionary<T>
{
private Dictionary<string, Tuple<Type, object>> _dict = new Dictionary<string, Tuple<Type, object>>();
public T this[string key]
{
get { return (_dict[key].Item1)_dict[key].Item2; }
set { _dict[key] = new Tuple(typeof(value), value); }
}
}
which does not compile for several reasons, of course. However, I can't even make this work with a generic class, and I do not want a generic class because I will then have to specify the type when instantiating, which is exactly what I'm trying to avoid.
Is there a solution to this? Am I meddling into things I shouldn't touch?

No, there is no such option.
As you noted, for:
public T this[] { get; set; }
you need some "generic-ness" at the outer scope, as the this[] also can't be generic on its own. So, your class/whatever would be generic-<T> and force the users not only to specify the T, but also to specify only one single T for all elements.
For Dictionary<string, Tuple<Type, object>> the best you can have is:
public object this[] { get; set; }
public IMyInterface this[] { get; set; }
this is because at the time of compilation, your whole dictionary-class does not have any information about the item types. The code is limited to object as in Typle<Type,object>. The only things you can do is to return an object, or try to cast it to some other known type, like interface.
If you resign from using a this[], you can try to make a 'smart getter':
public TValue GetItem<TValue>(TKey index) { ... }
public void SetItem<TValue>(TKey index, TValue value) { ... }
which would just do all the casting (like return (TValue)tuple.Item2). However, that would have some issues like difficult usage when used in context when "TValue" is unknown. So, you'd also probably need
public object GetItem(TKey index) { ... }
public void SetItem(TKey index, object value) { ... }
just to avoid cumbersome GetItem<object>. Of course, wherever the TValue versions are used, the user would need to specify the TValue explicitely (except for the SetValue where it'd be probably inferred, not necessarily correctly).
Now, let's get back to basics. What is your idea about
public T this[] { get; set; }
anyways, hm? As you bundle together the Type and Object in the Tuple, it seems like you want to be able to pack a heterogenous items into the Dictionary, right? So, tell me, how the final user and/or how the code/compiler would be able to guess wnat is being returned:
var foo = myDictionary["bar"];
what would be the type of the foo variable? Compiler can't guess, because at compilation myDictionary only know it will hold some Tuple<Type,object> but it does not hold anything now. Also, it actually does not even exist yet, since it's being compiled.. It is simply not possible to force a 'return value' to be "typed" with the exact type taken from your Tuple.
Also, why do you even carry the Type in that Tuple? The object kept in the dictionary knows its Type, always. You don't need to carry the Type for it, you can simply .GetType() on that object with just the same effect. If you'd want to preserve upcasted type information (example: have a Bar inherited from Foo, upcast Bar as Foo and put into magiccontainer, retrieve back as Foo not Bar), then you are a bit out of luck.. Even dynamic would not help with that and would return you "dynamic object" which would know itself to be "Bar" and which would allow you to dynamically call all Bar methods. I think that carrying the Type is completely unnecessary, unless you have some strong shielding/isolation requirements - but in that case, simple "carrying a Type and casting to it" will not help at all. For such things you will probably need dynamic proxies.
Since I already got chatty, last (a bit useless, but you may still want to hear it) note: It actually is possible to force a "cast" to a type stored in a 'Type'. You can do that with expressions. You can dynamically build an Expression<>, bind it with correct Type object, and invoke.
Borrowing code from https://stackoverflow.com/a/3983342/717732 it would look like:
public static ???? castAndReturn(object item, Type type)
{
var p = Expression.Parameter(typeof(object), "i");
var c = Expression.Convert(p, type);
var ex = Expression.Lambda<Func<object, ????>>(c, p).Compile();
return ex(item);
}
but again, what return type you'd put into the ???? placeholders, hm? The only possibilities are object, dynamic, or a custom well-known common-base-type. Back to square one. D'oh. Sorry. No really, way.

It sounds like you are trying to implement a property container exposing a generic indexer, which is (as you know) not possible in C#. However, a similar strategy can be implemented following the patterns seen in the IEditorOptions interface. In particular, note the following characteristics:
The strong type associated with a key is represented by creating the EditorOptionKey<T> generic type instead of using just a string.
The GetOptionValue<T> and SetOptionValue<T> methods replace your current use of an indexer property. The generic type parameter for these methods is inferred from the EditorOptionKey<T> passed as a parameter.
Code using this class might look like the following (using several fields from the DefaultOptions class):
IEditorOptions options = ...;
bool replicate = options.GetOptionValue(DefaultOptions.ReplicateNewLineCharacterOptionId);
options.SetOptionValue(DefaultOptions.IndentSizeOptionId, 2);
options.SetOptionValue(DefaultOptions.ConvertTabsToSpacesOptionId, true);

Related

DictionaryExtention, working for single items but not for List<Item>, why and how?

I am trying to get two different return values from dictionary extension methods for convenience. The first being an Item of the RealType, the other being a List<RealType>.
The problem / question is this: Getting a single RealType item works like a charm, getting the List crashes and calls for IConvertable implementation. Is there no build in call to convert a full list?
Edit: I am trying to convert from Base Class to Derived Class, not the other way around. Also, I 100% know the data will be of type Derived Class and the caller is passing the correct type each time, without any chance of error.
Why is that? Can I avoid it, without "dirty" tricks?
There are about two dozen RealType - classes that all extend from MyAbstractModel and get saved in a
List<Dictionary<string, MyAbstractModel>. Writing code for two dozen conversions seems like no good idea, when a small dirty (?) trick seems to do it as well.
Consider the following (working) DictionaryExtention class
public static class DictionaryExtenders
{
public static T GetItem<T>(this Dictionary<string, MyAbstractModel> instance, string key)
{
return (T)Convert.ChangeType(instance[key], typeof(T));
}
}
Called like this: RealType item = myDictionary.GetItem<RealType>("choosenIDString");
Edit: Each Dictionary can and will only ever have one type present. There won't ever be two different types stored in one. Yes, this code would allow that and spew out errors, but a saveguard is not needed in this case and is not part of my question.
Now in contrast, the following GetList<RealType> extention calls for IConvertable implementation:
public static List<T> GetList<T>(this Dictionary<string, MyAbstractModel> instance)
{
return (List<T>)Convert.ChangeType(instance.Values.ToList(), typeof(List<T>));
}
I feel like I am missing something here, because the following workaround also returns a List<RealType>, but does not call for IConvertable. I simply loop the dictionary and call GetItem<T>()each time.
public static List<T> GetList<T>(this Dictionary<string, MyAbstractModel> instance)
{
var temp = new List<T>();
foreach (RealType myType in instance.Values.ToList())
{
temp.Add(instance.GetItem<T>(myType.ID));
}
return temp;
}
This does not feel like a solid solution, but like a workaround. What am I missing here? Do the Lists give me a hard time due to faulty syntax on my side, or is there a reason I have to understand?
Your GetList implementations are not valid. All values in dictionary are instances of classes derived from MyAbstractModel but you can't cast them each other in all cases. For example, ModelA and ModelB are both derived from MyAbstractModel. But you can't cast ModelA to ModelB. You can write something like this:
public static List<T> GetList<T>(this Dictionary<string, MyAbstractModel> instance) where T: MyAbstractModel
{
return instance.Values.OfType<T>().ToList();
}
In that case you'll receive all values of particular type T.
you can try this way
public static List<T> GetList<T>(this Dictionary<string, yourModel> instance)
{
return instance.Values.Select(d => (T)Convert.ChangeType(d, typeof(T))).ToList();
}

Function pointers with differing return types in C# [duplicate]

I have object XML serialized messages coming into a class called MessageRouter. The XML contains the Type name it it was serialized from, and I need to be able to invoke different delegate methods depending on the type that are not known until runtime. I'm not extremely strong in generics so hopefully this will make sense to someone...
I'd like MessageRouter to provide a RegisterDelegateForType method like so:
myMessageRouter.RegisterDelegateForType(new Action<MySerializableType>(myActionHandler));
And then store the types, or the type's string representation in a Dictionary like this:
Dictionary<Type, Action<T>> registeredDelegates;
That way, I can do something like the following pseudocode, calling the type's assigned delegate and passing the deserialized object:
Type xmlSerializedType = TypeFromXmlString(incomingXml);
object deserializedObject = DeserializeObjectFromXml(xmlSerializedType, incomingXml);
// then invoke the action and pass in the deserialized object
registeredDelegates[xmlSerializedType](deserializedObject);
So my questions are:
How do you define a Dictionary that can contain a Type as a key and a generic Action<T> as a value, and have the RegisterDelegateForType method populate the dictionary?
If that's not possible, what's the best way to do this?
You cannot do this as described, for quite obvious reasons - even if somehow allowed, the last line of code in your example (the one which retrieves a delegate and then calls it) would be non-typesafe, as you're calling an Action<T> - which expects T as an argument - and yet passing it deserializedObject, which is of type object. It wouldn't work in plain code without a cast, why would you expect to be able to circumvent the type check for your case?
In the simplest case, you can do something like this:
Dictionary<Type, Delegate> registeredDelegates;
...
registeredDelegates[xmlSerializedType].DynamicInvoke(deserializedObject);
Of course this will allow someone to add a delegate which takes more or less than one argument to the dictionary, and you'll only find out at DynamicInvoke call, at run-time. But there isn't really any way to define a type which says "any delegate, but with 1 argument only". A better option might be this:
Dictionary<Type, Action<object>> registeredDelegates
and then registering types like this:
myMessageRouter.RegisterDelegateForType<MySerializableType>(
o => myActionHandler((MySerializableType)o)
);
The above snippet uses C# 3.0 lambdas, but you can do the same - if slightly more verbose - with C# 2.0 anonymous delegates. Now you don't need to use DynamicInvoke - the lambda itself will do the proper cast.
Finally, you can encapsulate the lambda creation into RegisterDelegateForType itself by making it generic. For example:
private Dictionary<Type, Action<object>> registeredDelegates;
void RegisterDelegateForType<T>(Action<T> d)
{
registeredDelegates.Add(typeof(T), o => d((T)o));
}
And now the callers can just do:
RegisterDelegateForType<MySerializableType>(myHandler)
So it's completely typesafe for your clients. Of course, you're still responsible for doing it right (i.e. passing an object of the correct type to the delegate you retrieve from the dictionary).
I am not sure that this completely answers your question, but here is a class I wrote that will accomplish what you want. I couldn't tell if you want your Action delegate to take a typed object or not, but in your pseudo code, you pass it an "object" to deserialize so I wrote my class accordingly and it therefore does not use generics:
public delegate void Action(object o);
public class DelegateDictionary {
private IDictionary _dictionary = new Hashtable();
public void Register<T>(Action action) {
_dictionary[typeof(T)] = action;
}
public Action Get<T>() {
return (Action)_dictionary[typeof(T)];
}
public static void MyFunc(object o) {
Console.WriteLine(o.ToString());
}
public static void Run() {
var dictionary = new DelegateDictionary();
dictionary.Register<string>(MyFunc);
// Can be converted to an indexer so that you can use []'s
var stringDelegate = dictionary.Get<string>();
stringDelegate("Hello World");
}
}
I believe this will accomplish what you want.

Cast instance to generic interface without knowing type

I have a generic interface called IValueBridge which serves as a generic bridge to get the values from any arbitrary object by providing the properties name (also nested properties are possible, e.g. myFoo.MyProp.Name):
public interface IValueBridge<in T> : IValueBridge
{
object GetValue(T instance, string attributeName);
}
Now there is an implementing class:
public class ValueBridge<T> : IValueBridge<T>
{
public object GetValue(T instance, string attributeName)
{
Func<T, object> f = // ...
return f(instance);
}
}
Now with this setting I wanto to use that bridge in order to get the values for any arbitrary object without knowing its type at compile-type.
What I WANT to achieve is something similar to this:
object bar = ...;
var bridge = new ValueBridge<typeof(bar>();
I know how to create instances of generic types via reflection using MakeTypeGeneric. However what Activator.CreateInstance returns is an object and I cannot cast it to the actual type Bar (which I don´t know at compile-time) and thus cannot access GetValue<T> on it.
Is there a way I can access GetValue<T> without any more reflection? I´d like to avoid more reflection as the method is called very often and calling it via reflection is considered quite slow. That´s why I cache the Func<T, object> to be called inside.
I found a quite nice solution using a wrapper-interface which IValueBridge<T> extends:
public interface IValueBridge
{
object GetValue(object instance, string attributeName);
}
Now my actual ValueBridge looks like this:
public class ValueBridge<T> : IValueBridge<T>
{
object IValueBridge.GetValue(object instance, string attributeName)
{
return this.GetValue((T)instance, attributeName);
}
public object GetValue(T instance, string attributeName)
{
Func<T, object> f = // ...
return f(instance);
}
Now you can use ((IValueBridge) myBridge).GetValue(...) . As the parameter can be cast to its actual type within the ValueBridge ((T) instance)) we can now invoke the generic version of the method directly without any reflection.
Note that you have to explicitely implement any of the two interfaces to avoid confusion which method to call from within the wrapper.
The reason I self-answer that question is that I got much head-ache on solving it and want to share the result of my thoughts to the community.

Can I ignore a generic type in a C# interface?

Background
I'm starting work on a little OSS library called Sieve.NET.
The signature lets someone define a Sieve as follows:
new EqualitySieve<ABusinessObject>().ForProperty(x => x.AnInt);
This actually returns a Sieve<ABusinessObject, int>, but I've done my best to ensure that users don't have to care about that part too too much.
The Task
I would like to find a way to put an interface on this, where I don't care about the property type at all -- only that it is consistent throughout.
So essentially, I would like to be able to declare an ISieve<TFilterObjectType>, and by able to have that Interface define something like:
ISieve<TFilterObjectType, TTypeIDontCareAbout> ForValue(TTypeIDontCareAbout);
My goal is to be able to have a class composed from ISieve<ABusinessObject> and not ISieve<ABusinessObject, int>.
Question
Is there a way for an interface to declare a type that effectively is a wildcard, and says "I don't care what type this is, only that it's consistent?"
My initial research says no but I'm hoping to be proven wrong.
Updates & Clarifications
What I'm really trying to figure out is:
I allow users to create an EqualitySieve<ABusinessObject>().ForProperty(x=>x.AnInt).
This actually returns an EqualitySieve<ABusinessObject, int> to the user, but since it's a fluent interface I remove them from having to care about that part.
I would like EqualitySieve, LessThanSieve, etc. to implement ISieve<ABusinessObject>.
I would like ISieve<ABusinessObject to enforce a contract whereby I could allow someone to call ForValues() and expect it to return an ISieve with the updated values.
However, at that point, the EqualitySieve<ABusinessObject> is actually an EqualitySieve<ABusinessObject, int>. But I don't particularly care about the property type at that point.
Essentially, since I'm abstracting the away the EqualitySieve<ABusinessObject, int> portion, I also wanted to see if I could abstract that away when referring to objects via the interface.
The long-term plan is that I want to have a SieveLocator, where classes can implement an IFindableSieve<ABusinessObject> that ideally would return an ISieve<ABusinessObject>. Then my goal would be to be able to find those Sieves for a given object.
So I'm thinking this is likely a limitation of my design and I'll have to find some other way around it. Any suggestions on that or references to a pattern I might not be seeing would be helpful as well.
You can place generic type parameters on both the interface and the interface's methods. So the following example would define a generic interface where the F method takes one of these "I don't care what type this is, only that it's consistent" parameters.
interface I<T>
{
//The generic type parameter U is independent of T.
//Notice how F "forwards" the type U from input to output.
Tuple<T, U> F<U>(U u);
}
Consider the following toy class:
class C : I<char>
{
public char Value { get; set; }
public Tuple<char, U> F<U>(U u)
{
return Tuple.Create(Value, u);
}
}
Here's some example usage:
I<char> instance = new C { Value = '!' };
Tuple<char, int> x = instance.F(5); // ('!', 5)
Tuple<char, string> y = instance.F("apple"); // ('!', "apple")
Updates
I allow users to create an EqualitySieve<ABusinessObject>().ForProperty(x=>x.AnInt).
This actually returns an EqualitySieve<ABusinessObject, int> to the user, but since it's a fluent interface I remove them from having to care about that part.
I would like EqualitySieve, LessThanSieve, etc. to implement ISieve<ABusinessObject>.
Using the ideas I mentioned above, you can do what (I think) you want.
interface ISieve<T>
{
//It's still not clear what you actually want in this interface...
}
static class Sieve
{
public EqualitySieve<T> Equality<T>()
{
return new EqualitySieve<T>();
}
public LessThanSieve<T> LessThan<T>()
{
...
}
}
class EqualitySieve<T> : ISieve<T>
{
//Notice how the property type P is independent of T
//and can be inferred here from the passed expression
public EqualitySieve<T, P> ForProperty<P>(
Expression<Func<T, P>> propertyExpression)
{
return new EqualitySieve<T, P>
{
PropertyExpression = propertyExpression
};
}
}
class EqualitySieve<T, P> : ISieve<T>
{
public Expression<Func<T, P>> PropertyExpression { get; set; }
}
Usage:
//Assuming MyObject.MyProperty is an int property
//s has type EqualitySieve<MyObject, int>
var s = Sieve.Equality<MyObject>().ForProperty(x => x.MyProperty);
There may be some tricks so callers don't need to specify a type on a generic method (think how LINQ works), but unfortunately your research was correct, there is no way to infer a type while composing a class that uses that type.
The closest you can get to it is having two layers of interfaces where the outer layer does not use any of the functions that rely on the TTypeIDontCareAbout type.
interface ISieve<TFilterObjectType,TTypeIDontCareAbout> : ISieve<TFilterObjectType>
{
TFilterObjectType ForValue(TTypeIDontCareAbout forValue);
}
interface ISieve<TFilterObjectType>
{
TFilterObjectType SomeOtherFunction();
}
I don't know how to solve all your problems but I think Timothy's approach is what you want to go for the two points
I allow users to create an EqualitySieve<ABusinessObject>().ForProperty(x=>x.AnInt).
This actually returns an EqualitySieve<ABusinessObject, int> to the user, but since it's a fluent interface I remove them from having to care about that part.
interface ISieve<TFilterObjectType>
{
TFilterObjectType SomeOtherFunction();
EqualitySieve<TFilterObjectType, T> ForProperty<T>(Func<TFilterObjectType, T> selector);
EqualitySieve<TFilterObjectType, T> ForProperty<T>(Expression<Func<TFilterObjectType, T>> selector); //This is how you would do it if you wanted IQueryable support.
}

How to define generic extension method that returns type of sub generic

I have a definition like this:
public static IQueryable<D> ReturnDTO<E, D>(this IQueryable<E> query)
where D : BaseDTO, new()
where E : BaseObjectWithDTO<D, int>
{
//expression tree code to convert
}
BaseObjectWithDTO defines what type it's DTOs are. Hence I would have thought the by defining E I would have been also defining D.
But IQueryable.ReturnDTO() requires that the generic parameters be specified like this:
IQueryable.ReturnDTO<someEntity, someDTO>();
Which is obviously UGLY.
I tried making this IQueryable<E> as this IQueryable<BaseObjectWithDTO<D, int>> instead but then this has nothing as the in of the func because it won't take a type inferred by the Generic Parameter of the IQuerayble:
var projection = Expression.Lambda<Func<E, D>>(memberInitExpression, itemParam);
Ideas on how to get this to not require the types be passed every time?
Unfortunately, C#'s generic type inference system isn't as powerful as it could be. If you include a parameter involving D, then it can infer it. For example...
public static IQueryable<D> ReturnDTO<E, D>(this IQueryable<E> query,
IQueryable<BaseObjectWithDTO<D, int>> dummy)
// now you can do...
myQueryable.ReturnDTO(myQueryable);
// instead of
myQueryable.ReturnDTO<BaseObjectWithDTO<BaseDTO, int>, BaseDTO>();
It's confusing and arguably a poor design to pass the same variable in twice, but it's better (IMHO) than having to explicitly specify the types or resort to reflection or other runtime techniques to extract the types (when that's otherwise unnecessary).
Since you aren't actually going to use the dummy parameter, it doesn't matter what the value is, as long as the type is right, so you might still be able to use this at the end of a query chain, e.g. this will still return the expected value, even though you pass in two different IQueryables.
var result = otherQueryable.Where(...).ReturnDTO(otherQueryable);
If you prefer to be slightly less cryptic, you could make the dummy parameter D dummy, and then e.g. myQueryable.ReturnDTO(default(SomeDTO)) (here using default as a clear way of getting a null or default value without having a reference to a variable/field/property of that type) if you prefer.
I don't think it is possible as you currently have it designed, this MSDN page states that type inference is not possible in this scenario:
The same rules for type inference apply to static methods and instance
methods. The compiler can infer the type parameters based on the
method arguments you pass in; it cannot infer the type parameters only
from a constraint or return value.
That means you have to pass in a parameter of your type to this method for the compiler to be able to infer the types.
You have to specify the type, but it doesn't have to be done explicitly in the q.Return<E,D>(). There are ways that you can pass specify the type parameter so that it can be inferred implicitly. To do that, you'll need to change the signature a bit.
public static IQueryable<D> ReturnDTO<E, D>(this IQueryable<E> query, D dtoTypeExample = default(D))
where D : BaseDTO, new()
where E : BaseObjectWithDTO<D, int>
{
//expression tree code to convert
}
Now, even though there's a default parameter, the compiler won't be able to get it unless you pass some argument in. The thing you pass in doesn't have to be used by the method in any other way though. For example, assume you have:
public class ProductDTO : BaseDTO {
public static ProductDTO Empty { get { return new ProductDTO(); } }
}
public class Product : BaseObjectWithDTO<ProductDTO,int> {
public static IQueryable<Product> QuerySource { get; set; }
}
You could then call:
ProductDTO dto = Product.QuerySource.ReturnDTO(ProductDTO.Empty);
I'm not saying that this is necessarily a good idea, but you could do it. Also, it doesn't have to be the actual type that you pass in - you just need to pass in something that's close enough for the compiler to infer the intended type. For example, you could have a signature like:
public static IQueryable<D> ReturnDTO<E, D>(this IQueryable<E> query, Func<D,D> dtoIdentity = default(Func<D,D>))
where D : BaseDTO, new()
where E : BaseObjectWithDTO<D, int>
{
//expression tree code to convert
}
then if you have:
public class ProductDTO : BaseDTO {
public static ProductDTO Identity(ProductDTO dto){ return dto; };
}
public class Product : BaseObjectWithDTO<ProductDTO,int> {
public static IQueryable<Product> QuerySource { get; set; }
}
You could then call:
ProductDTO dto = Product.QuerySource.ReturnDTO(ProductDTO.Identity);
This might make more semantic sense to some, but it's somewhat subjective. Once again, I'm not recommending this, just saying that you can do it. If you do decide to do it though, it might save you a little work to have a self-referential generic base (Warning: Eric Lippert discourages this kind of thing). But anyway, your design would then look like:
public abstract class BaseDTO<T> where T : BaseDTO<T>, new()
{
public static T Empty { get { return new T(); } }
}
public class ProductDTO : BaseDTO<ProductDTO> { }
You could also add the type constraint to your ReturnDTO method if you want to enforce an invariant that all DTOs were then self-referential derivatives of BaseDTO<T> with public parameterless constructors. But, if you're trying to write what would conventionally be considered good code you probably won't do any of this and you'll just close your eyes and explicitly use the parameter constraint if you think it's ugly.
There is one other thing I thought of, which wouldn't be so frowned upon. Think about the Queryable.Cast<T> and Queryable.OfType<T> methods. They take a non generic IQueryable parameter but returns an IQueryable<T>. If you make sure to validate your assumptions about the parameter, it's probably clean enough. Then you would lose some compile-time type-safety though. You would need to have a non-generic base like BaseObjectWithDTO that BaseObjectWithDTO<TData,TKey> would inherit from. Your method would then look like:
public static IQueryable<D> ReturnDTO<D>(this IQueryable<BaseObjectWithDTO> query)
where D : BaseDTO, new()
{
if(query == null) throw new ArgumentNullException("query");
if( !typeof(BaseObjectWithDTO<D,int>) .IsAssignableFrom(query.GetType().GetGenericParameters()[0]))
throw new ArgumentOutOfRangeException("query");
//expression tree code to convert
}
That's not terrible. But it might not be good either. It's probably better than the other options I listed, but who knows.
Another syntax that might work for you just occurred to me, but it's also pretty abusive. Imagine you did go the BaseDTO<T> where T : BaseDTO<T>,new() route. You could declare the method on that type to extract the DTO queryable. This is what I'm thinking:
public abstract class BaseDTO<T>
where T : BaseDTO<T>, new()
{
public static T From(BaseObjectWithDTO<T,int> entity){
if(entity == null) throw new ArgumentNullException("entity");
//expression tree code to convert
}
}
then you don't really need that method ReturnDTO as an extension method anymore, because you have normal LINQ. You could still add it as syntactic sugar if you want, but using these semantics instead, your call ends up looking like:
IQueryable<ProductDTO> dtoQuery = from entity in Product.QuerySource select ProductDTO.From(entity);
which can also be written as
Product.QuerySource.Select(entity => ProductDTO.From(entity));
and if you were using an IEnumerable instead of an IQueryable could be
Product.QuerySource.Select(ProductDTO.From);
Please remember: All I'm saying is that you can do things this way. I'm not saying you should.

Categories

Resources