I am fairly new to C# and I am trying to create a generic extension method that that takes any enumeration as the parameter. Based on the enumeration I want to retrieve an attribute that has been applied within the enumeration. I want to be able to use this extension method across multiple enumerations. I currently only have the static method directly in my class that contains the enumeration and it looks like this:
public static string GetIDForEnum(Enum enum)
{
var item = typeof(Enum).GetMember(enum.ToString());
var attr = item[0].GetCustomAttribute(typeof(DescriptionAttribute), false);
if(attr.Length > 0)
return ((DescriptionAttribute)attr[0]).Description;
else
return enum.ToString();
}
How do I make this a generic extension method?
How do I make this a generic extension method?
You can't, at the moment... because C# doesn't allow you to constrain a type parameter to derive from System.Enum. What you want is:
public static string GetIdForEnum<T>(T value) where T : Enum, struct
... but that constraint is invalid in C#.
However, it's not invalid in IL... which is why I created Unconstrained Melody. It's basically a mixture of:
A library with useful generic delegate and enum methods
A tool to run ildasm and ilasm to convert permitted constraints into the ones we really want
You could do something similar yourself - but it's all a bit hacky, to be honest. For enums it does allow an awful lot more efficient code though...
Related
I was wondering if C# supported implicit type discovery for class generics.
For example, such functionaly exists on method generics.
I can have the following method:
public void Foo<T>(T obj);
And call it like this:
int n = 0;
instance.Foo(n);
As you can see, I'm not specifying the <int> generic constraint. It's being implicitly discovered, because I passed an int value.
I want to accomplish something similiar on a class definition level:
internal interface IPersistenceStrategy<E, T> : IDisposable
where E : UniqueEntity<T>
I want it to be defined as IPersistenceStrategy<MyEntity>, where MyEntity is an UniqueEntity<int>.
As you can see, the T type param, is being implicitly discovered from MyEntity.
However, this does not work. I have to supply the T param explicitly:
IPersistenceStrategy<MyEntity, int> myStrategy;
Why is this functionality not working? Is C# compiler not smart enough to discover my type param automatically?
Is there some way to accomplish what I am looking for?
There is no type inference in generic type declarations on initialization. You can only omit the generic argument when calling a generic method but it is not the case with initializing a generic type for example:
var list = new List { 2, 3, 4 };
Here you may expect compiler to see that you wanna create a list of int so there is no need to specify type argument.But it is not the case.
In your specific example let's assume compiler has inferred this :
IPersistenceStrategy<MyEntity> myStrategy;
as IPersistenceStrategy<MyEntity,int> then what should happen if there is another declaration in the same assembly such as:
interface IPersistenceStrategy<T> { }
Ofcourse this would cause an ambiguity. So that might be the one of the reasons why it is not allowed.
C# has type inference for methods, but not for constructors. This feature was proposed to be in C# 6 version, but seems was removed from release according to Mads Torgersen (http://blogs.msdn.com/b/csharpfaq/archive/2014/11/20/new-features-in-c-6.aspx).
Also have a look to Languages features in C# 6 and VB 14, i.e. there is no mention about it
Class StudentFeeCollection
{
public static bool CheckAdmissionMonth(int AdmissionNo)
{
}
public static DataTable CheckAdmissionMonth(int AdmissionNo)
{
}
}
Is this possible or not, please tell me.
You can use out parameter:
class StudentFeeCollection
{
public static void CheckAdmissionMonth(int AdmissionNo, out bool result)
{
........
}
public static void CheckAdmissionMonth(int AdmissionNo, out DataTable tbl)
{
.......
}
No, that's not possible. You need to make sure that the signature of each overload is unique.
From the documentation:
Changing the return type of a method does not make the method unique as stated
in the common language runtime specification. You cannot define overloads that
vary only by return type.
Reference:
http://msdn.microsoft.com/en-us/library/vstudio/ms229029(v=vs.100).aspx
This is not possible. Imagine you're the compiler or the runtime--how would you know which return type the code was asking for? If you really need to support returning multiple datatypes from a method, using generics is your best bet. That said, looking at your specific example, I suggest not doing it here. Having one method that returns either a boolean or a DataTable seems like a pretty shoddy design.
You can overload by argument types in c# but not by return type.
As Arshad said you can use out/ref parameters since these are arguments and not return types.
Also you can't overload by generic constraints of arguments(say having 2 versions where one is a struct and another is a class). see https://msmvps.com/blogs/jon_skeet/archive/2010/10/28/overloading-and-generic-constraints.aspx
one reason to avoid return type overloading, from the c++ language description:
The reason is to keep resolution for an individual operator or function call context-independent.
note: in some programming language like haskell you can overload by return types
see Function overloading by return type? for more info
I'm trying to write a generic method that will return specific markup when passed an enum. Below is the method which has been reduced to the minimum required code for this question.
public static string GetMarkup(Type enumType)
{
StringBuilder builder = new StringBuilder();
foreach (var val in Enum.GetValues(enumType))
{
builder.Append(val.ToString());
}
return builder.ToString();
}
The method is called like this where CopyType is an enum:
GetDropDownListHtml(typeof(CopyType))
The goal is to be able to call ToString() extension methods I've written for the enums I'll pass into this method. The problem is that to make the method generic, I need to use var to declare my variable in the foreach declaration, but that boxes it. Instead of an enum of CopyType, I have an object that is the boxed CopyType.
In response, I've tried many thinks like this, but to no avail:
((typeof(enumType))val.ToString()
Any ideas?
There's no way to use extension methods to do this to a specific enum. You either need to extend your extension method to support all Enum types, add an is statement in there which you can use to only cast it when necessary, or write a special overload to this function which you call just for this type of enum. This has to do with how extension methods are actually implemented.
The compiler turns an extension method into its static form: myCopyType.ToString() becomes CopyType.ToString(myCopyType) when compiled. But with your scenario (or even with generics) the compiler can't tell what type to use, because the type isn't determined until runtime.
This leaves the three choices above.
In my own code, I went with the first option, based on the code here. You'll be able to call .GetLabel() on any Enum type, and you can put your special labels on this one specifically.
Additionally, you'll need to use foreach (Enum val in ... instead, so as to make sure the compiler knows it's an Enum.
Is it in anyway possible ( preferably without using any third party libs), to create a function whose type is determined at runtime in C#?
e.g
public static void myfunc(var x)
{
System.Windows.Forms.MessageBox.Show(x); //just an example
}
NOTE: I want the runtime to determine the type of the parameter and do not want to later cast the parameter to another type, as would be necessary if I use generics. e.g I don't want:
myfunc<T>(T x)
// and then :
MessageBox.Show((string)m);
UPDATE:
I am actually making a function parser for my programming language, which translates to C# code. In my language, I wanted the parameter types to be determined at runtime always. I was looking for some good C# feature for easy translation.
e.g
in my language syntax:
function msg << x
MessageBox.Show x
end
needed to be translated to something that didn't ask for a type at compile time, but would need one at runtime.
e.g
public static void msg(var x)
{
System.Windows.Forms.MessageBox.Show(x);
}
The keyword introduced for runtime binding in C# 4 is dynamic.
public static void myfunc(dynamic x)
This allows you to make assumptions about x that are unchecked at compile time but will fail at runtime if those assumptions prove invalid.
public static void MakeTheDuckQuack(dynamic duck)
{
Console.WriteLine(duck.Quack());
}
The assumption made here is that the parameter will have a method named Quack that accepts no arguments and returns a value that can then be used as the argument to Console.WriteLine. If any of those assumptions are invalid, you will get a runtime failure.
Given classes defined as
class Duck
{
public string Quack()
{
return "Quack!";
}
}
class FakeDuck
{
public string Quack()
{
return "Moo!";
}
}
And method calls
MakeTheDuckQuack(new Duck());
MakeTheDuckQuack(new FakeDuck());
MakeTheDuckQuack(42);
The first two succeed, as runtime binding succeeds, and the third results in an exception, as System.Int32 does not have a method named Quack.
Generally speaking, you would want to avoid this if possible, as you're essentially stipulating that an argument fulfill an interface of some sort without strictly defining it. If you are working in an interop scenario, then perhaps this is what you have to do. If you are working with types that you control, then you would be better served trying to achieve compile time safety via interfaces and/or base classes. You can even use different strategies (such as the Adapter Pattern) to make types you do not control (or cannot change) conform to a given interface.
If you need to know the type... then you need to know the type. You can't have your cake and eat it too.
First off, the cast in your example is unnecessary as all objects implement ToString(). Instead of telling us what you think you need, tell us what problem you are trying to solve. There is almost certainly a solution either via generics or the use of the dynamic keyword (though dynamic is rarely needed), but we need more info. If you add more I'll update this answer.
You could use a type of object or, if you don't know how many items are available, you could use a params object array, i.e. params object[] cParams.
I don’t mean overloading. This might include new Types of classes which I haven’t created yet.
EDIT:
I want to create a method which will return a value of the type it gets as a parameter. I can get a parameter of type object, but I don’t want to return it that way and then cast, I want the return-value itself to be of the same type as the parameter.
You could use reflection:
var returnType = typeof(SomeClass).GetMethod("SomeMethodName").ReturnType;
You can create a generic method which returns a type to be determined. As long as you declare your new classes correctly then they should work.
There are a number of ways of doing this, a search for return generic type c# turns up several different techniques of varying complexity. Fundamentally you have:
public T DoStuff<T>()
{
...
}
however, the "..." is the bit that depends on your application.
Based on your updates, the method you want will be something like:
public T MyMethod<T>(T input)
{
// DoSomething
T result = default(T); // Create your instance of T here
return result;
}
Yes, it's called reflection.
This should answer your question: http://msdn.microsoft.com/en-us/library/system.reflection.methodinfo.returntype.aspx
You can use generic type and generic methods to do that
C# Generic Methods