As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
In C++, you can write code like this:
template<class T>
T Add(T lhs, T rhs)
{
return lhs + rhs;
}
But, you can't do something like this in C#:
public static T Add<T>(T x, T y) where T : operator+
{
return x + y;
}
Is there any reason why? I know it could be accomplished through reflection (generic Add with objects and then run type checking over it all), but that's inefficient and doesn't scale well. So, again, why?
There is no inherent reason this could not exist. The way generic type constrains are implemented is through interface calls. If there were an interface that provided an operator+ this would work.
This interface would be required for all relevant types, though, to be as general as the C++ template-based analog.
Another issue would be that .NET has no multiple dispatch. The interface call would be asymmetric: a.Plus(b) could mean something different than b.Plus(a). Equals has the same problem, btw.
So this issue probably did not meet the "usefulness"-bar or the "cost/utility"-bar. This is not an issue of impossibility, but of practical concerns.
Proof that it is possible: ((dynamic)a) + ((dynamic)b).
The CLR doesn't natively support such constraints, and the C# design team evidently decided to support the same set of constraints as the CLR. Presumably both the CLR team and the C# team felt that the benefits of implementing such a feature didn't outweigh the costs of speccing, implementing, and testing it.
If you want to use a .NET language that does support such constraints, consider taking a look at F#.
There are several possible ways to implement operator constraints and all of them are either non-trivial (and would probably require a change of the CLR) or have significant drawbacks (e.g. they would be slow, much slower than adding two integers).
And this is something that is relatively easy to work around (either the slow, general and unsafe way of using dynamic, or the fast, type-specific and safe way of having bajillion overloads). Because of that, such feature is probably considered “nice to have” but far from important enough to warrant such changes.
Related
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
Which do you think is better..
if (thing.GetType() == typeof(thisthing))
{
//do stuff for this type of thing.
}
Or give the objects an Enum property
if (thing.TypeName == NamesEnum.thisthing)
{
//do stuff for this type of thing.
}
Neither of these is a particularly extensible or maintainable approach.
It's typically better to design this directly into a virtual method in your type hierarchy, and just call the method. This allows other classes to override and provide custom functionality as appropriate.
In your case, the thisthing type (which should be named ThisThing if you want to follow .NET naming conventions) would just have a DoStuff method which could be virtual if needed, and call it.
It depends:
if (thing.TypeName == NamesEnum.thisthing)
will run more performant then GetType() as, this a simple comparison of 2 numeric values.
But:
if (thing.GetType() == typeof(thisthing))
is more more "flexible": when you do some refactoring, change type name or whatever, this condition will still work.
But will fail in condition, if 2 types belong to 2 different assemblies, instead in first case this still will be matched as equal,as you campare not types but just enum values.
In short, there is no best approach, just most suitable for your needs.
IF you are working with basic types that don't have sub types...
your first example can be shortened nicely to
if (thing is typeof(thisthing))
Depends on the situation really. If you get to a lot of different types you're going to want a switch statement at some point, so I would say option 2 if there are going to be a lot of types.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
During a code review I presented a method quickly to the team that I had made static and one person agreed that there was no reason for it to not be static and a person disagreed saying that he would not make it static because it wasn't necessary and just to be on the safe side for future modifications and testing.
So I did quite a bit of research and obviously it's a specialized case but I would like to know what you would do in this situation and why?
(Its basically a helper method I call from a few different methods, a very low traffic page. More for my knowledge and learning on Static.)
private IEnumerable<Category> GetCategoryByID(int id, Context context)
{
var categoryQuery = from selectAllProc in context.SelectAll_sp()
where selectAllProc.CategoryID == id
select selectAllProc;
return categoryQuery;
}
Making private methods static is a form of micro-optimization; the method call is slightly faster. But the difference is almost too small to be meaningful.
Generally speaking, you should mark a method static when it:
Doesn't interact in any way with instance members, and
You would like to have the ability to call it without instantiating the class, as in Class.Method()
Ordinarily, methods like your example would go into their own static helper class, if they are used in more than one place.
If I were you I would ask my self the following questions.
Is it something which is related to type or instance of type?
If the answer is yes, I would be slightly inclined to make it static else, make it non static.
If you can give us some more information, the community can come up with some good options.
The first remark that comes to my mind is that by declaring this method static and possibly using it in multiple places in your code you are introducing a Service-locator kind of dependency.
As far as I know the main problem with it is that implicit dependencies are introduced, i.e. they can't be inferred by looking at method signatures.
As a consequence it can be much harder to assess the impact of a modification of your static method on the rest of your system.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
Why is the default decision in C++, C#, and Ada 95 to use static method binding, rather than dynamic method binding.?
Is the gain in implementation speed worth the loss in abstraction and re-usability?
In general, you can consider that you have todesign the base class for extensibility. If a member function (to use the C++ vocabulary) isn't designed to be overridden, there is a good chance than overriding it will in practice not be possible and for sure it won't it be possible without knowledge of what the class designer think is implementation details and will change without giving you prior notice.
Some additional considerations for two languages (I don't know C# enough to write about it):
Ada 95 would have had compatibility issues with Ada 83 if the choice was different. And considering the whole object model of Ada 95, doing it differently would have make no sense (but you can consider that compatibility was a factor in the choice of the object model).
For C++, performance was certainly a factor. The you don't pay for what you don't use principle and the possibility to use C++ just as a better C was quite instrumental in its success.
The obvious answer is because most functions shouldn't be virtual. As AProgrammer points out, unless a function has been designed explicitly to be overridden, you probably can't override it (virtual or not) without breaking class invariants. (When I work in Java, for example, I end up declaring most functions final, as a matter of good engineering. C++ and Ada make the right decision: the author must explicitly state that the function is designed to be overridden.
Also, C++ and (I think) Ada support value semantics. And value semantics doesn't work well with polymorphism; in Java, classes like java.lang.String are final, in order to simulate value semantics for them. Far to many applications programmers, however, don't bother, since it's not the default. (In a similar manner, far too many C++ programmers omit to inhibit copy and assignment when the class is polymorphic.)
Finally, even when a class is polymorphic, and designed for inheritance, the contract is still specified, and in so far as is reasonable, enforced, in the base class. In C++, typically, this means that public functions are not virtual, since it is the public functions which define and enforce the contract.
I can't speak about Ada, but for C++ two important goals for the design of C++ were:
backwards compatibility with C
you should pay nothing (to the extent possible) for features that you don't use
While neither of these would necessarily dictate that dynamic binding couldn't have been chosen to be the default, having static method binding (I assume you mean non-virtual member functions) does seem to 'fit' better with these design goals.
I'll give one of the other two thirds of Michael Burr's answer.
For Ada it was an important design goal that the language be suitable for system's programming and use on small realtime embedded devices (eg: missile and bomb CPUs). Perhaps there are now techniques that would allow dynamic languages to do such things well, but there certianly weren't back in the late 70's and early 80's when the language was first being designed. Ada95 of course could not radically deviate from the orginal language's basic underlying design, any more than C++ could from C.
That being said, both Ada and C++ (and certianly C# as well?) provide a way to do dynamic method binding ("dynamic dispatch") if you really want it. In both it is accesed via pointers, which IMHO are kind of error-prone. It can also make things a bit of a pain to debug, as it is tough to tell from sources alone exactly what is getting called. So I avoid it unless I really need it.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
Just a thought.
Wouldn't it be useful to have optional type parameters in C#?
This would make life simpler. I'm tired of having multiple classes with the same name, but different type parameters. Also VS doesn't support this very vell (file names) :-)
This would for example eliminate the need for a non-generic IEnumerable:
interface IEnumerable<out T=object>{
IEnumerator<T> GetEnumerator()
}
What do you think?
I am definitely for it.
I'm currently writing helper methods for different scenarios where I want to pass references to different members and methods of classes. To accomplish this I'm taking, for example, an Expression<Func<TIn, TOut>> as argument to the helper (that lets me reach the method with a lambda expression, thus keeping everything strongly typed).
BUT - I currently need to define a new helper method for each different number of input arguments, since I need to have a different amount of generic arguments to it. Instead of
HelperMethod<TIn>(Expression<Action<TIn>> arg) // Yes, C# can distinguish
HelperMethod<TOut>(Expression<Func<TOut>> arg) // these two from eachother
HelperMethod<TIn, TOut>(Expression<Func<TIn, TOut>> arg)
HelperMethod<TIn1, TIn2, TOut>(Expression<Func<TIn1, TIn2, TOut>> arg)
// etc
I could make do with, at the most, two methods:
HelperMethod<TIn>(Expression<Action<TIn>> arg)
HelperMethod<TOut, TIn1 = DummyType, ...>(Expression<Func<TIn1, ..., TOut> arg)
In my case, it would avoid a lot of code duplication...
What would be the main use for this language feature? I can see that it could help with some administrative tasks like file names and less typing and such but beyond that I don't see how useful this would be.
Also, this feature would significantly complicate any generic constraints that could be placed on the generic type parameter and the default type itself would have to function as a sort of generic constraint itself.
I think this would complicate the language without offering any real benefit to the developer.
It's not clear to me what exactly you are proposing. Currently there may be types with the same name but different type parameters, but which aren't related in any way by inheritance - what would your proposal do then?
Furthermore, if the base class library were redesigned from the ground up, there almost certainly would be no non-generic IEnumerable interface - it only exists because the CLR didn't support generics when the interface was introduced, and the generic interface inherits from it only so that legacy code will continue to work. Newly declared classes are being created for a CLR which does support generics, so that issue is no longer relevant.
I recently came across a case that could have used something like this, just not quite. I had a method that performs a transformation of sorts, between class A and its associated class AChild and class B and class BChild. Usually, the pair A/AChild was the same as B/BChild, but sometimes A was a base class of B and AChild a base class of BChild.
It would have been nice to be able to say that my type parameter TB defaulted to TA, and that TBChild defaulted to TAChild.
Note that this was a situation in which it was necessary to write out the type parameters, as inference would not work.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Can anybody help me where to start and what are the essential things to learn about collections (non-generics) and generics?
Defining Collections
Collections in C#
An introduction to C# Generics
I also recommend the following book which has pretty much all the details you could want on Generics in .NET 2.0 onwards, including Generic classes, methods, delegates and constraints, how they differ from C++ templates, and the generics in the BCL.
.NET 2.0 Generics
For a really brief explanation: Regular collections store objects. The system doesn't know what kind of object is stored, so you have to cast them to the desired type when you work with them. Generic collections declare what kind of object is being put in at the time you create it. Then you always know what is there. it's like the difference between an object array and a String array.
I would definitely check out the list of links on the page PK posted for a more thorough understanding.
1) Classes can be defined with a generic type.
public class MyClass<TClass>
2) The types can be constrained using this syntax.
where TClass: struct
3) Methods also can gave generic types.
public TMethod ConvertTo<TMethod>()
4) Full Example
public class MyClass<TClass> where TClass: struct
{
private TClass _Instance;
public MyClass(TClass instance)
{
_Instance = instance;
}
public TMethod ConvertTo<TMethod>()
{
return (TMethod)Convert.ChangeType(_Instance, typeof(TMethod));
}
}