Create a generic list from multiple different lists - c#

I am writing a Silverlight and WCF project.
I have used the Entity Framework in Silverlight to get the data from the database, I have multiple pages where I use EF.
Now, I have more than 100 types of entity class and hence multiple known list types.
In my WCF interface I want to create one generic function where I can accept all this list types as one generic parameter.
So my WCF function should be like
public string TestBadal(List<Object> list)
{
return "test";
}
My question here is, how can I cast all the known lists to List. I am fairly new to this so any help will be much appreciated.
Thank you.

you can use T
public static List<T> o<T>(List<T> a)
{
return a = new List<T>();
}

As Sophex states you can write a generic function to process a List<> or better still an IList<> of anything.
So your example would become,
public string TestBadal<T>(IList<T> list)
{
return "test";
}
This is very generic and requires and implies little about T. This may be sufficient for the processing you want to perform but, you don't say.
In general, you should view your method signature as a promise that the caller has to make to the function. You should limit the promise to only what is required for your function to do its job. This way, the promise is easier to make and your function can get reused more with less commitment from the caller.
Your function as it stands, doesen't actually need a parameters and would be better defined as a string const but say, all you wanted to do was enumerate the items you could use,
public string TestBadal<T>(IEnumerable<T> entities)
{
foreach(T entity in entities)
{
...
}
}
If your processing is especially related to the EF nature of the data source you could do,
public string TestBadal<TEntity>(EntitySet<TEntity> entities)
where TEntity : class
{
...
}
If you need to know somthing about the type in the list then you have two sensible options.
Either you require the types to implement a certain interface, this essentialy makes your function non-generic and could be awkward with in conjunction with EF.
public string TestBadal(IEnumerable<IDefinedType> definedTypeInstances)
{
foreach(IDefinedType instance in definedTypeInstances)
{
var x = instance.SomeDefinedProperty;
}
}
Or, you can take the non generic parts of the function as a typed delegate parameter, keeping the function generic, possibly somthing like this.
public string TestBadal<T>(
IList<T> list,
Func<T, string> stringSelector)
{
var result = new StringBuilder();
for(var i = 0; i < list.Count; i++)
{
result.AppendLine(stringSelector(list[i])
}
return result.ToString();
}
You could call this function with a lambda expression somthing like this,
var result = TestBadal(entities, e => e.SomeStringProperty);
I hope this answer both gives you some ideas and illustrates my point that the right answer depends on what you want your function to achieve.

Related

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.
}

Array of different generics

Long story short, I would like to be able to store generics using different type parameters in an array, by using a parent type to all the types used. MSDN mentioned it was impossible, as generics were invariant types, but a comment stated that this changed since the 4.0 framework.
Here is a basic example of what I would like to do:
public class Animal
{
}
public class Dog : Animal
{
}
public class Cat : Animal
{
}
public class MyGeneric<T>
{ }
public class MyInheritedGeneric<T> : MyGeneric<T>
{ }
static void Main(string[] args)
{
MyGeneric<Animal>[] myGenericArray = new MyGeneric<Animal>[]
{
new MyGeneric<Dog>(),
new MyInheritedGeneric<Cat>()
};
}
This returns the similar errors:
Cannot implicitly convert type
'InheritanceTest.Program.MyGeneric<InheritanceTest.Program.Dog>' to
'InheritanceTest.Program.MyGeneric<InheritanceTest.Program.Animal>'
Cannot implicitly convert type
'InheritanceTest.Program.MyInheritedGeneric<InheritanceTest.Program.Cat>'
to 'InheritanceTest.Program.MyGeneric<InheritanceTest.Program.Animal>'
Is there any way to store generics in an array using the parent class of the type, or is this simply impossible? I really hope it is possible, otherwise it will make my program a nightmare...
EDIT: A bit more context!
I am making classes to generate enemies in a game. I call them Templates (nothing to do with actual template classes, I could very well have called them Blueprints or Factories). An enemy constructor takes in a Template, which it uses to determine its own values. When the game loads, the templates are used to generate all enemies, using their Generate() function, which returns an array of the corresponding type they are assigned to produce. All the objects to be created with a template are to have a constructor taking a template as their sole parameter.
public class Template<T>
{
protected static Random random = new Random();
protected int _amount;
public int Amount
{
get { return _amount; }
}
public virtual T CreateInstance()
{
return (T)Activator.CreateInstance(typeof(T), this);
}
public virtual T[] Generate()
{
T[] objects = new T[Amount];
for (int i = 0; i < Amount; ++i)
objects[i] = CreateInstance();
return objects;
}
}
Here is a summary of the BasicZombie.cs file, which contains the actual enemy class and the template.
class Tpl_BasicZombie : Tpl_Enemy<BasicZombie>
{
public Tpl_BasicZombie()
{
_hp = 4;
_speed = 3;
_amount = 10;
}
}
class BasicZombie : GroundEnemy
{
public BasicZombie(Tpl_BasicZombie template)
: base(template, TextureManager.Get("zombie_base"), 1, 8)
{ }
public void StuffHappens()
{ }
}
When loading the game, I would like to go through all the templates in an array to load enemies from them. I know that I could do this manually, but every time I will create a new type of enemy I would need to add it manually to the code (thus probably forgetting more than once).
My two options were:
1- Use a generic, and the above problem ensues.
2- Use a non-generic, and store the type inside, which would anchor the return type Generate() function. This would mean the generate function would output an array of objects, array which would need to be converted to the suitable type every single time a template generates an array of enemies.
I have a space in my head that tells me there is an elegant solution to all this, and I hope it is right!
Yes, C# 4 supports generic variants - but only in the declarations of interfaces and delegates, so you won't be able to do it in this case. Of course you could potentially create an interface:
public interface IGeneric<out T>
and then implement that in your classes, at which point you could create an IGeneric<Animal>.
If you can give more details about what you're trying to achieve, we may be able to help you find an alternative approach.
Jon Skeet's info aside, you might be able to do something like this:
public MyGeneric<T2> ToOtherType<T2>()
{
if (typeof(T2).IsAssignableFrom(typeof(T)))
{
// todo: get the object
return null;
}
else
throw new ArgumentException();
}
new MyGeneric<Dog>().ToOtherType<Animal>(),
new MyInheritedGeneric<Cat>().ToOtherType<Animal>()
If an array is going to hold more than one type of item, the items are going to have to be stored in heap objects which are separate from the array itself (if some of the types are structs, they'll have to either be boxed or stored as a field in a generic type which derives from a non-generic one). In most cases, the simplest thing to do will be to identify a common ancestor type for everything you'll be storing in the array, and simply typecast array elements as needed. There are a few cases where that won't be feasible, however. If, for example, your collection is going to hold objects whose type is unknown but is constrained to more than one interface, it will be necessary to pass those objects to generic routines whose method type parameter is similarly constrained, and the types that may be passed to your routine have no common ancestor which satisfies all constraints, there won't be any single type to which all members of your collection can be cast that would allow them to be passed as a suitable generic.
If the objects in your collection will only be passed to a small number of routines, it may be possible to have the generic method which adds items construct delegates to suitably invoke all the necessary routines and store those delegates as part of the collection. Lambda expressions or anonymous delegates may be convenient for this.
For example, suppose one will need to be able to feed items that are stored in a list to the Wibble<T> method of various IWibbler objects and the Wobble<T> method of various IWobbler objects, where the T types have interface constraints I1 and I2.
interface IWibbler { void Wibble<T>(T param, int param) where T : I1,I2; }
interface IWobbler { void Wobble<T>(T param, string param) where T: I1,I2; }
private struct WibbleWobbleDelegateSet
{
public Action<IWibbler, int> Wibble;
public Action<IWobbler, string> Wobble;
static WibbleWobbleDelegateSet Create<T>(T param) where T: I1, I2
{
var ret = new WibbleWobbleDelegateSet ();
ret.Wibble = (IWibbler wibbler, int p2) => { wibbler.Wibble<T>(param, p2); };
ret.Wobble = (IWobbler wobbler, string p2) => { wobbler.Wobble<T>(param, p2); };
return ret;
}
}
Calling WibbleWobbleDelegateSet.Create<T>(T param), with a suitably-constrained param, will yield a non-generic structure which contains delegates that can be used to pass the parameter supplied at struct creation to any IWibbler.Wibble<T>() or IWobbler.Wobble<T>() method.
This approach is only directly usable if the list of routines that will be called is known. If one needs to be able to call arbitrary routines with constrained generic parameters, it's possible to do that either with some tricky interfaces or with Reflection, but such things get more complicated.

How do a turn a generics based method into a lambda with Func<...>

How do a turn this
public static List<T> CreateListOfAnonymous<T>(T unused) {return new List<T>();}
into a lamda. I just can't seem to work it out. as a generic of a generic gives an error
i.e:
Func<T,T> ..... fails because its looking for a real type.
My goal is to use the logic from that method above, but without a method, just internally inside some method.
How do I turn a generic method into a lambda?
You don't. Lambdas cannot be generic. Sorry! That's one of the differences between nominal and anonymous functions; anonymous functions cannot be generic, nominal ones can.
Can you explain what is the scenario that is requiring generic anonymous methods? If there is a really good reason to add this to the language, we could consider it for a hypothetical future version.
My goal is to use the logic from that method above, but without a method, just internally inside some method.
If the method or type you're using the lambda in is generic (so that you have a type that is concrete in-context) then you can get this to work:
public void SomeMethod<T>()
{
Func<T, List<T>> createList = CreateListOfAnonymous;
var list = createList(default(T));
}
// ...
class SomeClass<T>
{
public void SomeMethod()
{
Func<T, List<T>> createList = CreateListOfAnonymous;
var list = createList(default(T));
}
}
If neither is true for your code, or you want to keep T for the lambda as an open generic (potentially of some other type than the method or class's generic parameters), then it won't be possible, as leppie mentioned.
I've found in cases where I've wanted to do this type of thing in the past (to avoid repeating myself), I only had a few types I wanted to bind to in the method. So I just bit the bullet and created one concrete version for each type I wanted to support:
public void SomeMethod()
{
Func<List<string>> createStringList = () => CreateListOfAnonymous("");
Func<List<int>> createIntList = () => CreateListOfAnonymous(0);
var list1 = createStringList();
var list2 = createStringList();
var list3 = createStringList();
var list4 = createIntList();
var list5 = createIntList();
// ...
}
If I understand you correctly, it is not possible.
You cannot have instances of open generic types.

Implement same Generic Interface 2 times with different Generic parameter

I had to implement 2 interface same time with different generic parameter as below. I get confused enough about it. I had no idea which one of them iterate itself in foreach. Now i understand first one is implicitly choosen.
I have tried new BarList().GetEnumerator() but i can not specify type parameter on method level.
Only solution i have found it that casting it to interface like(new BarList() as IEnumerable<string>)
After confusing about it enough. I just wanted to know that this design is not really good idea ? I have to avoid to implement same generic interface one more time ?
class Program
{
static void Main(string[] args)
{
foreach (var item in new BarList())
{
}
}
}
class BarList: IEnumerable<string>, IEnumerable<int>
{
public IEnumerator<int> GetEnumerator()
{
throw new NotImplementedException();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
IEnumerator<string> IEnumerable<string>.GetEnumerator()
{
throw new NotImplementedException();
}
}
Edit:
Let me explain why i am going in this way.
I had to Implement IPagedList<T> interface which is inherited from IList<T>. I wanted to write extension method which convert it to My view model. like below
GetAll().ToPagedList(pageindex);//which is returning IPagedList Then i wanted to use it like below;
GetAll().ToPagedList(pageindex).ToViewModel<T,TViewModel>();
For achieve this I tried to return IPagedList<ViewModel> by that extension method.In that case I have to implement IPagedList 2 times with different parameter. But this strategy made confusing things. This is reason of it.
This seems a bit confusing. Why not make it explicit what is happening by adding the enumerators as properties rather than implementing them on the class. For example,
class ProductCollection
{
public IEnumerable<int> EnumerateTheInts { get { //code to produce enumerator }}
public IEnumerable<string> EnumerateTheStringss { get { //code to produce enumerator }}
}
It isn't always bad to implement an open generic interface twice on an object. For example, IHandle could be implemented by a class which can handle two types of T. However, I would find it confusing to implement IEnumerable twice, because you might not enumerate the type you expect in a for-each or in LINQ. Same reasoning for implementing more than one indexer incidentally. The type of your indexer will determine your result, which I can testify to being extremely confusing!
The compiler is picking the IEnumerator<int> GetEnumerator method by following the rules in 8.8.4 of the C# language specification which first looks for an accessible GetEnumerator() method on the BarList type. The only one of those which is available is the one returning IEnumerator<int>.
If you had made that method use explicit interface implementation as well, then it would have gone onto the later stages of section 8.8.4, which states that if there is more than one type T such that there is an implicit conversion from the expression type (BarList here) to IEnumerable<T> then an error is produced.
I would say this is a confusing design - I would probably add properties or methods to retrieve appropriate "views" on the data.
I'd avoid it. However, it depends on your usage.
It will be okay if you just wanted to pass the instance into a function that expects a IEnumerable<string> parameter explicitely:
you won't have to cast
the function won't even 'see' the other interfaces implemented, so there isn't any confusion.
YMMV
Your current design is confusing. While you have not provided any information about the nature of the collection itself, from the name, I can assume you are supposed to iterate over a bunch of products. Perhaps, you should simply have a class of type Product with a string property and an int property and simply return an IEnumerable<Product> instead.
This way, with LINQ extension methods, you can compose the IEnumerable<T> object you actually mean with:
collection.Select(product => product.IntegerProperty)
collection.Select(product => product.StringProperty)
Of course, you can provide helper methods inside the object as well:
class ProductCollection : IEnumerable<Product> {
public IEnumerable<Product> GetEnumerator() {
// ... return Product objects here.
}
public IEnumerable<int> AsIntegerCollection() {
// yield the integer collection here
}
public IEnumerable<string> AsStringCollection() {
// yield the string collection here
}
}
What are these collections of string and ints? I suppose they mean something in relation with the Product (for example Name, Id, etc...) so I would rather do something like this:
class ProductCollection : IEnumerable<Product>
{
public IEnumerator<Product> GetEnumerator()
{
...
}
public IEnumerator<string> ProductNames // a helper to enumerate product names
{
...
}
public IEnumerator<int> ProductIds // a helper to enumerate product ids
{
...
}
}

Less defined generics in c#?

Is there a way to use a collection of a generic class, without supplying the underlying type ?
Let's explain :
Here is what I'd like to have :
class TimeSerie<TValue> {
enter code here
}
List<TimeSerie<?>> blah;
Here is what I have to do so far :
class TimeSerie {}
class TypedTimeSerie<TValue> : TimeSerie {}
List<TimeSerie> blah;
So, any way to use the nice first solution ? (although I guess it would raise problems when trying to cast, for a loop for example ...)
You can make your using code generic too... but at some point you do have to specify the type argument. You're not going to be able to create an instance of the generic type without the type argument being known. You can provide that information at execution time using reflection if you must, but it has to be there somehow.
I dont see based on your question why you cannot derive your custom collection from ICollection<T> or List<T> (or maybe derive from ICollection and delegate the calls to a field of type List<T> you store internally?
(It's entirely possible I'm just not getting it, but can you give a small bit more sample code?)
Why not ?
List<TimeSerie<Object>> blah;
Then after you specify your object. Also define your base class accordingly.
Note that some 'mumbling' is possible in relation to anonymous types with c# thanks to two things:
Type inference
unification of identical anonymous types
If you are happy to rely on these two things remaining fixed (there are no guarantees on this, especially in relation to 2) then the following may be useful.
public static class Mumble
{
public static HashSet<T> HashSet<T>(T prototype)
{
return new HashSet<T>();
}
public static List<T> List<T>(T prototype)
{
return new List<T>();
}
}
You can use it like so:
var set = MumbleSet(new { Foo="", Bar="", Baz=0 });
var list = MumbleList(new { Foo="", Bar="", Baz=0 });
set.Add(new { Foo="x", Bar="y", Baz=1 });
set.Add(new { Foo="a", Bar="b", Baz=1 });
list.Add(new { Foo="a", Bar="b", Baz=1 });
var intersection = list.Intersect(set);
var concat = list.Concat(set);
This works well in cases where you have anonymous types you wish to populate into some other collection for use elsewhere within a method. A common use would be reading from a database query into a set for latter checking for existence within a loop where expressing this as a series of linq queries was either too cumbersome or too expensive.
For your motivating example you would have to add the following:
class TimeSerie<TValue>
{
// or some other constructor equivalent
public TimeSerie(TValue value) { /* assign the value */ }
}
static class TimeSerieMumble
{
public static TimeSerie<TValue> New<TValue>(TValue value)
{
return new TimeSerie<TValue>(value);
}
}
Then you could use the code like so:
var tsList = Mumble.List(TimeSerieMumble.New(new { Name="", Value=0 }));
foreach (var x in from c select new { c.Name, c.Value })
{
tsList.Add(TimeSerieMumble.New(new { x.Name, x.Value }));
}
Mumbling which 'leaks' into the public api is not feasible in c# 3.5 unless the type is to be mumbled through a series of type inferred generic methods in the same way as the above example. I have never seen a case where such a thing was useful given the resulting contortions required to the calling code. I would not think it would improve readability either. As a rule of thumb using more than the two levels of mumbling in the Name/Value example is likely to lead to serious complications down the line.
As others have said, there's no easy way to do this in C#.
However, if it's really important, it is possible to faithfully encode this pattern using a few extra types, although it's a bit ugly:
interface ITimeSeriesUser<X> {
X Use<T>(TimeSeries<T> series);
}
interface ITimeSeriesUser {
void Use<T>(TimeSeries<T> series);
}
interface ITimeSeries {
X Apply<X>(ITimeSeriesUser<X> user);
void Apply(ITimeSeriesUser user);
}
class TimeSeries<T> : ITimeSeries {
X Apply<X>(ITimeSeriesUser<X> user) { return user.Use(this); }
void Apply(ITimeSeriesUser user) { return user.Use(this); }
/* Your existing code goes here */
}
Now you can create a List<ITimeSeries> instance which holds TimeSeries<T>
values regardless of their type arguments, and you can use ITimeSeriesUser
implementations to manipulate them. Obviously this requires quite a bit of boilerplate,
but if you need a faithful way to express the concept of a TimeSeries<?> then this may be your best bet.

Categories

Resources