Why it is not possible to cast something that extends number to number?
Here is simple example in which I'm trying to pass enum as a generic argument to function.
enum Ev {A, B}
function fun<E extends number>(x: {[ix: number]: any}, e: E)
{
return x[<number>e]
}
// no error here, so I assume is true that `Ev extends number`
fun({0:0}, Ev.A)
It seems a bit inconsistent that some type extends number but I get this error when trying to cast it to number:
Neither type 'E' nor type 'number' is assignable to the other.
Edit: Here is almost the same example but with class instead of number (this compiles without error):
class A {}
function fun<E extends A>(x: {[ix: number]: any}, e: E)
{
return x[<A>e]
}
Primitive types cannot be inherited from, as some have special "abilities" that require a special instance, and creating a new derived object would prevent that ability. For instance, there is no way to call the string constructor for a new custom derived object, so no way to apply it to a user instance. This is why nothing inherits from number, or anything else.
Why it is not possible to cast something that extends number to number?
As Ryan has pointed out in this issue, it seems like a bug in the language; however, take note that this form of constraint is only useful when the return type of the function is the constraint on the type parameter. For example:
function f<T extends number>(input: T) : T { return input; }
var t = f(Ev.A); // t : Ev
An issue with the constraint in the function you provided, is that it doesn't prevent passing in a number value. Since it's not possible to constrain to an enum member, you might as well just define your function with the constraint on the parameter instead:
function fun(x: {[ix: number]: any}, e: number)
{
return x[e];
}
A complaint you had with doing this was that it wasn't self documenting code. I would say it's better to give your function a descriptive name that says its intent rather than relying on generics that offer no constraint benefit beyond a number constraint. Also remember that there's no way to force a developer to write the generic part when calling the function. They can easily write fun({0:0}, Ev.A) instead of fun<Ev>({0:0}, Ev.A).
Related
I'm really struggling to find a name for a type of function I've come across.
Here is the function in question:
https://github.com/go-fsnotify/fsnotify/blob/master/fsnotify.go#L32
This is how I'm using it (as per the fsnotify example):
select {
case event := <-watcher.Events:
log.Println("Event Triggered: ", event)
In that Println 'event' is returning the formatted string as per the function above, I'm just struggling to understand how a straight call to 'event' is using that function yet I would be expecting it to be accessed like the struct fields (event.Name, event.Op):
event.funcForReturningNicelyFormattedEvent()
It feels like this is a 'default' function as it has no name and it just returns the formatted data - I'm struggling to come up with the name/type/search term so I can find out more and understand the concept and importantly the reasoning behind it better.
Any help is appreciated.
It's very simple - println uses the String() method on any struct that implements it automatically. This is a classic use case of Go's implicit interfaces: every struct that has the methods an interface includes, is considered to be implementing the interface.
If it has func String() string it is considered a Stringer and used by fmt. You can use it on your own structs too, of course.
Function Println checks if the passed value implements interface Stringer. If it does it calls method String on this value. Event type implements that interface by supplying its implementation of String method in the excerpt you linked to.
In Go you don't have to declare that you implement interface.
In my base-repository class
i wrote this function to make possible to retrive a sorted data collection from the DB.
T is a generic defined at Class level
public abstract class RepositoryBase<T>
where T : class
The code is this:
public IList<T> GetAll<TKey>(Expression<Func<T, bool>> whereCondition, Expression<Func<T, TKey>> sortCondition, bool sortDesc = false)
{
if (sortDesc)
return this.ObjectSet.Where(whereCondition).OrderByDescending(sortCondition).ToList<T>();
return this.ObjectSet.Where(whereCondition).OrderBy(sortCondition).ToList<T>() ;
}
My goal was to introduce a generic sort parameter so that i could call the function in this way:
repo.GetAll (model=>model.field>0, model=>model.sortableField, true)
i mean that i could specify the sorting field directly via anonymous function and so using Intellisense...
Unfortunately this function doesn't work as the last code line generate errors at compile time.
I tried also to call:
repo.GetAll<Model> (model=>model.field>0, model=>model.sortableField, true)
but this don't work.
How should i write the function to meet my goal?
i'm working with EF 5, c#, .NET 4.5
You're using ObjectSet which implements IQueryable<T>. That is extended by methods on System.Linq.Queryable, which accept Expression<Func< parameters. It is correct to use those Expression parameters, as you intend for execution to occur in the database, not locally.
A Func is an anonymous delegate, a .net method.
An Expression is a tree, which may be compiled into a Func, or may be translated into Sql or something else.
You showed us a really abstract use of the method, but not an actual use of the method, or the compiler error. I suspect the error you may be making is confusing the two type parameters.
You said:
repo.GetAll<Model> (model=>model.field>0, model=>model.sortableField, true)
But this generic parameter for this method represents the type of sortableField. If sortableField isn't a Model - this is wrong.
Instead, you should be doing something like this:
Repository<Person> myRepo = new Repository<Person>();
myRepo.GetAll<DateTime>(p => p.Friends.Count() > 3, p => p.DateOfBirth, true);
If specifying the sort type breaks your intended pattern of usage, consider hiding that key by using an IOrderer: Store multi-type OrderBy expression as a property
I have written a function that returns a User Defined Type.
How can i return a empty UDT in case of any error from the function?
I tried setting function to 'Nothing',but it is throwing 'Object Required' error.
Thanks in advance.
If at all possible, use a Class/Object instead. Even doing something as simple as turning this type:
Public Type EmpRecord
FName As String
LName As String
HiredDate As Date
End Type
into a class can be done by adding a Class to your project called EmpRecord and including just this in it:
Public FName As String
Public LName As String
Public HiredDate As Date
Then you can return Nothing from a function that gets an error while retrieving the record.
In VB6, a user-defined type is a "value type", while a class is a "reference type". Value types are typically stored on the stack (unless they're a member of a class). Reference types are stored as a pointer on the stack pointing to a place in the heap where the actual instance data is stored.
That means a reference to a class can be Nothing (the pointer is zero), whereas a value type can't.
There are multiple ways to solve your problem:
Add a Boolean member to your user-defined type to indicate success or failure.
Create another "wrapper" UDT like (see below) and return it from your function.
Change your UDT into a class, which can be Nothing (as tcarvin said).
Write the function to return a Boolean and take a ByRef parameter. The results are written to the parameter passed in if the function result is True. (A lot of people don't like this, but it's a common solution you should be aware of.)
Wrapper:
Public Type Wrapper
Success As Boolean
Inner As YourOriginalUDT
End Type
Function with ByRef:
Function Foo(ByRef Result As YourOriginalUDT) As Boolean
...
If Success Then
Foo = True
Result.A = A
Result.B = B
Result.C = C
... etc. ...
End If
End Function
A UDT can't be empty.
You can either use a "dummy" unintialised UDT, or just set all it's members back to the default values.
My code is simply:
public override C Calculator<C>(Team[] teams, Func<Team, C> calculatorFunc)
{
return teams.Average(calculatorFunc);
}
I get this error:
Error 2 The type arguments for method 'System.Linq.Enumerable.Average(System.Collections.Generic.IEnumerable, System.Func)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
How can I fix this?
You can't - at least in the current form. There is no Average overload available that works on completely generic values (i.e. for all types C as you specified).
Average needs lists of numbers (int, double, float ...) or a conversion function that produces numbers. In the current form, you could call Calculator<string> and it would make absolutely no sense to compute the average of strings.
You'll just have to restrict the method to a specific numeric type (or provide overloads), but generics simply won't work.
The Enumerable.Average method does not have an overload which works on a generic type. You're trying to call Average<TSource>(IEnumerable<TSource>, Func<TSource, C>), which does not exist.
In order to use average, you'll need to specify one of the types (for C) that actually exists, such as double, decimal, etc.
Instead of writing:
Calculate(team, calcFunc);
You will have to write:
Calculate<MyClass>(team, calcFunc);
However, you really should know what calculatorFunc is returning --- I'm going to assume that all of the ones you use return the same value type (whether it be decimal or int of float). In which case, you could define it as:
public override int Calculator(Team[] teams, Func<Team, int> calculatorFunc)
{
return teams.Average(calculatorFunc);
}
Then you have no generics in the declaration at all to worry about.
My 1st objective is to filter the types based on a specific interface with a generic.
My 2nd objective is to obtain the type of the generic parameter itself.
public UserService : IUserService, IDisposable, IExportableAs<IUserService>
{
...
}
I cannot assume the structure of the class, its interfaces (if any at all) or alike. The only thing I know I am targetting ExportableAs<T> from my shared assembly that was used to create this plugin. But yet, I need to register the type dynamically.
So, I am using a generic interface to mark the type to export. In this case, it's IUserService. I am doing this assuming some nifty Linq query can give me what I want. But, I am having a little trouble.
Here's what I have so far:
assembly.GetTypes()
.Where(t => t.GetInterfaces().Any(i =>
i.IsGenericType &&
i.GetGenericTypeDefinition() == typeof(IExportableAs<>))
).ToList()
.ForEach(t => _catalogs.Add(
new ComposablePart()
{
Name = t.FullName,
Type = t // This is incorrect
})
);
This is working, but notice the comment above for "This is incorrect". This type is the derived class of UserService.
What I need in my end result are:
The generic type pass into the IExportableAs<T> (IUserService in this case)
The derived class type (in this case, UserService)
This question got a good up-vote as it got me close (as you can see above): How to determine if a type implements a specific generic interface type But, I need to go one step further in finding that generic type.
Feel free to mangle my linq above.
Thanks in advance!
Got it
assembly.GetTypes().SelectMany(t => t.GetInterfaces(), (t, i) => new { t, i })
.Where(ti => ti.i.IsGenericType &&
ti.i.GetGenericTypeDefinition() == (typeof(IExportableAs<>)))
.Select(ti => new ComposablePart() {
Name = ti.t.FullName,
Type = ti.i.GetGenericArguments()[0]
});
[Edit] In my excitement, I didn't leave my test program running long enough to throw an Exception on the interface that wasn't generic. Thought the .NET Framework had been especially clever there. Corrected code now that I know it isn't.