I've been studying code of some different libraries, and notice that some will provide equivalent generic and non-generic functions in the same class.
One example is the IServiceLocator interface of the Common Service Locator project:
public interface IServiceLocator
{
object GetInstance(Type serviceType);
object GetInstance(Type serviceType, string key);
IEnumerable<object> GetAllInstances(Type serviceType);
TService GetInstance<TService>();
TService GetInstance<TService>(string key);
IEnumerable<TService> GetAllInstances<TService>();
}
The impression I get is that this is for maximizing accessibility, perhaps from COM. Absent those concerns, this seems like redundant code. Is there anything I'm missing?
Sometimes you know the type you need at compile time, at which point generics can give you compile-time safety and neater code.
Sometimes you only know the type you need at execution time, at which point generics become a pain in the neck, because you need to call them via reflection.
Providing both options gives the flexibility to handle both situations as well as possible.
Probably because the generic type is better for syntax and users will prefer it since it can cast it to the correct type, but for example, if the type is looked up at run time using reflection, you can't use the generic option and need to use the one that takes a Type.
In addition, generics are always resolved at compile time. Think of it as using the generic one when you know the type at compile time, and the non-generic during runtime.
The reason is the non-Generic will use an implied generics by checking its type so that you do not have to mention the type.
Related
For a generic class, foo<T> I can specify methods that only are available to certain types of the class, for example
public static void(this foo<int> val) is a valid declaration, as is
public static void(this foo<float> val) and in this way, I can specify different behaviors for a generic I intend to use the same way, handling the difference between them in their individual methods. Most useful case of this is to add Arithmetic functions to Vectors, Matrices, and Sets while still having them generic. (Since there is for some god forsaken reason still no INumeric constraint to define only types which support the basic operators)
Is there an equivalent functionality for static variables. The objective being, I can accomplish the following:
foo<int>.Zero and foo<float>.Zero and have each one be different, and not conflict with each other, returning a foo of the appropriate type, but without throwing errors in the case where foo<bar>.Zero because there is no "Zero" concept for an object like bar
C# does not provide with syntax that allow you to define field for property extensions, or static extensions for classes.
To achieve this, you should use some static property like foo.ZeroOfFloat as some C# standard APIs are defined like that.
It looks very pretty and cleaned when you are using more generic things, but this is not the correct use case of generic.
"Generic" means that it is general, for type irrelavent use, therefore it is different from template definitions in C++ that supports specialization. Technically, generic definitions in C# is compiled and delivered as IL, rather than as source code in C++, which means the compilation happens before a certain type is plugged into a generic definition and there cannot be a specialization for a single type.
Although there are some generic constraints for reference types, value types, delegates, or native structs etc., that limit the use of generic definition to some type of types. This disallows some use cases, rather than supporting something.
Although you could make use of that there could be different extension methods on a generic type that is closed with different type arguments (that gives you a feeling of template specialization), that is not by design.
Do not achieve a specific logic in generic definition. Definitions like ZeroOfFloat are never bad practices.
I have an API which includes some methods that take in a type parameter. I am now converting them to generic methods as part of improving the API (more type-safe), while keeping the non-generic version around for backward compatibility.
Current - to be obsoleted:
public object MyMethod(object value, Type expectedType)
New:
public T MyMethod<T>(object value)
However, Mymethod calls a private helper method which also takes in a type parameter:
private object HelperMethod(object value, Type expectedType)
Question: should I also make this private helper method generic?
I have my own answer below, but I would like to know if I'm missing something. I appreciate your insights very much.
My answer is no, I should not make this private method generic.
Reason 1: this helper method is private, so even if I made it generic, it doesn't improve the API.
Reason 2: If I make it generic, then the non-generic public methods will have to use reflection to pass the type parameter to this generic method, which means more overhead.
Making your private helper method generic does improve the API by carrying the generic type-specificity all the way through your implementation. Your implementation isn't fully realizing the type safety benefits of generics if you throttle the type down to a core that juggles typeless System.Objects around.
For example, why is the parameter to MyMethod still a System.Object? If that parameter originates in source, chances are good that it should be a type parameter too. If the parameter originates in data, you're probably better off with System.Object. Generics are most useful when they are used with source code, because source code expressions implicitly provide the type in most contexts.
The hidden costs of generics depends on the mix of types that will be used with the API. If most of the types will be value types (built-ins and structs), then switching the API to generics could raise your memory consumption because the generic code must be jit'd differently for each value type. If the majority of types used with your generic API are reference types (classes and interfaces), code/memory explosion isn't a concern because all reference types share the same JIT'd code.
Whether the cost of having the old API call the new generic API is a) measurable and b) acceptable depends entirely upon what you're doing in your private helper method - in particular, what the private helper method does with the Type parameter.
If the helper method implementation is fairly lightweight and you determine (by performance measurements) that the cost of adapting the old API to call the new generic helper is unacceptable, I would consider duplicating the helper method implementation, side by side, one in the old style and one in the new generic style. This eliminates crossover conversion costs between the API styles and eliminates the risk of introducing new bugs into the old API, at the cost of slightly increased internal code maintenance efforts.
I think it depends on the amount of time you plan to support the non-generic method, how often it will be called, what the impact on the reflection will be, etc. etc.
I would think you would want the generic functionality as much as you can to take advantage of the type-safety you want. Then retro-fit the non-generic version to use the generic version if necessary, and eventually deprecate it as soon as you can.
I need to be able to determine if a given method or property comes from a particular interface and is explicitly implemented.
Has anyone done this and is it actually possible to get this information by the means of .NET reflection?
Update
As can be seen in comments below the accepted answer, the actual thing I am trying to accomplish is to call the method that implements a particular interface via reflection. Since the possibility to have multiple interfaces with the same method signature, I wanted to determine the right implementation to invoke based on the interface. In my scenario, the implementation type, interface and method name are determined at runtime, so I cannot use simple casting
in my case.
Explicitly implemented interface methods in C# are private in the target class. You can use this fact and create this extension method to return only these methods:
static IEnumerable<MethodInfo> GetExplicitlyImplementedMethods(this Type targetType,
Type interfaceType)
{
return targetType.GetInterfaceMap(interfaceType).TargetMethods.Where(m => m.IsPrivate);
}
Note: this is for C# only.
UPDATE: But, from your requirements, it seems that you only want to know which methods implement which interface methods, without really caring about whether the implementation is implicit or explicit. For a solution that works across languages then, this would suffice:
static IEnumerable<MethodInfo> GetImplementedMethods(this Type targetType,
Type interfaceType)
{
return targetType.GetInterfaceMap(interfaceType).TargetMethods;
}
If when using reflection a method is private and its name contains a ., like "System.IDisposable.Dispose", then it is an explicit implementation.
For example IEnumerable<T> interface:
public interface IEnumerable<out T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}
In this interface the generic type is used only as a return type of interface method and not used as a type of method arguments thus it can be covariant. Giving this, can't compiler theoretically infer the variance from the interface? If it can, why does C# requires us to set co/contravariance keywords explicitly.
Update: As Jon Skeet mentioned this question can be spited into sub-questions:
Can compiler infer generic type's co/contravariance by how it is used inside current generic type and all it's base types?
For example.. How many generic interface parameters from .NET Framework 4.0 can be marked co/contravariant automatically without any ambiguity? About 70%, 80%, 90% or 100%?
If it can, should it apply co/contravariance to generic types by default? At least to those types which it is capable to analyze and infer co/contravariance from the type usage.
Well, there are two questions here. Firstly, could the compiler always do so? Secondly, should it (if it can)?
For the first question, I'll defer to Eric Lippert, who made this comment when I brought exactly this issue up in the 2nd edition of C# in Depth:
It's not clear to me that we reasonably could even if we wanted to. We can easily come up
with situations that require expensive global analysis of all the interfaces in a program
to work out the variances, and we can easily come up with situations where either it's
<in T, out U> or <out T, in U> and no way to decide between them. With both bad
performance and ambiguous cases it's an unlikely feature.
(I hope Eric doesn't mind me quoting this verbatim; he's previously been very good about sharing such insights, so I'm going by past form :)
On the other hand, I suspect there are still cases where it can be inferred with no ambiguity, so the second point is still relevant...
I don't think it should be automatic even where the compiler can unambiguously know that it's valid in just one way. While expanding an interface is always a breaking change to some extent, it's generally not if you're the only one implementing it. However, if people are relying on your interface to be variant, you may not be able to add methods to it without breaking clients... even if they're just callers, not implementers. The methods you add may change a previously-covariant interface to become invariant, at which point you break any callers who are trying to use it covariantly.
Basically, I think it's fine to require this to be explicit - it's a design decision you should be making consciously, rather than just accidentally ending up with covariance/contravariance without having thought about it.
This article explains that there are situations that the compiler cannot infer and so it provides you with the explicit syntax:
interface IReadWriteBase<T>
{
IReadWrite<T> ReadWrite();
}
interface IReadWrite<T> : IReadWriteBase<T>
{
}
What do you infer here in or out, both work?
I have an interface method
public void Execute(ICommand command);
which needs to pass known subtypes of ICommand to an apropriate Handle(SpecificCommand command) method implementation and do some generic handling of unknown types. I am looking for a universal (i.e. not requiring a giant switch) method of doing so, something similar to
Handle(command as command.GetType()); // this obviously does not compile
I know I could register the handlers somehow, e.g. store them as delegates in a dictionary, but this still requires duplicating the handling logic (once in the specific Handle(...) method signature, once in the delegate reqistration). If I populate the dictionary by inspecting my class with reflection (looking for Handle(XXX command) methods), I'll get a performance hit.
To summarize: how can I downcast an object (upcasted by the call to Execute(ICommand command)) to invoke a method requiring a concrete type without knowing which type it is at compile time.
Well, the "correct" answer is that Handle() should be a method in ICommand, so that instead of Handle(command), you'd be saying command.Handle().
The cast is emitted at compile-time, so you need to know the type at compile-time. The overloading is also determined at compile-time - so by the time you actually know the concrete type to use, it's too late.
I don't see that you'd actually be duplicating any logic by using delegates. Alternatively, if you do it with reflection, you can build delegates very easily using Delegate.CreateDelegate - you'll only get a performance hit once, and after that it'll be very fast. See my blog entry about Delegate.CreateDelegate for more information.
I think I'd decide to use a hand-built dictionary or one built with reflection based on how many methods I had and how often they change. You'll probably find KeyedByTypeCollection useful for the dictionary.
You can't, and why would you want to?
That's the whole reason we have polymorphism. If you want to have custom behaviour that is specific to certain types, then the behaviour should live in the type itself and be invoked via a function declared in the base class type.
I've tried working out a way which would work using Double Dispatch (http://en.wikipedia.org/wiki/Double_dispatch), but it seems that you have a situation where the number of classes implementing ICommand and those implementing Execute() can vary at run-time (or, at least between compile & run-time, which is essentially the same thing), so the only solution I can see it use the dictionary as Jon Skeet propsed.