I have an enum
public enum FileExtentions {
mp3,
mpeg
}
And I have a FileInfo of which I want to check if the extension is in the previous enum.
I was hoping I could do a
FileExtensions.Any(e=>e.ToString().Equals(file.Extension));
But that would have been too awesome.
Any ideas?
What's the reason behind Any … Equals? Did you overlook Contains?
bool result = Enum.GetNames(typeof(FileExtensions)).Contains("mp3");
While pressing submit I thought of the answer myself:
Enum.GetNames(typeof(FileExtensions)).Any(f=>f.Equals("."+file.Extension))
Enum.IsDefined will take a string containing the name of an enum value. The only ugliness is that you have to strip the leading period off of File.Extension and it's case sensitive:
Enum.IsDefined(typeof(FileExtension), file.Extension.Substring(1).ToLower())
Edit: Extension method goodness to get close to your desired syntax:
IEnumerable<string> GetNames(this Type t) {
if (!t.IsEnum) throw new ArgumentException();
return Enum.GetNames(t);
}
typeof(FileExtensions).GetNames().Any(e=>e.ToString().Equals(file.Extension));
Personally, though, I'd still rather the IsDefined route:
bool IsDefined(this Type t, string name) {
if (!t.IsEnum) throw new ArgumentException();
return Enum.IsDefined(t, name);
}
typeof(FileExtension).IsDefined(file.Extension);
You can extend the FileInfo type with the following extension method:
public static bool HasExtension(this FileInfo file)
{
var ext = file.Extension.StartsWith(".") ? file.Extension.Substring(1)
: file.Extension;
return Enum.GetNames(typeof(FileExtensions))
.Any(f => f.Equals(ext));
}
and use it like:
bool hasExtension = file.HasExtension();
You can do that with the System.Enum type:
string extension = Enum.GetName(typeof(FileExtensions), FileExtensions.mp3);
if (extension == file.Extension)
// do something here
Update:
Ah, I misunderstood that you want to check the entire enum for the extension and not that a specific enum value matches the extension. In that case, your approach with GetNames() is the route - sorry you can't mark your own answer as accepted for your own question. ;-)
The best way is to use Enum.IsDefined function. It pretty easy, in your case:
if (Enum.IsDefined(typeof(FileExtentions), file.Extension))
General solution:
Enum.IsDefined(Type, Object)
Your solution is:
Enum.IsDefined(typeof(FileExtentions), FileInfo)
Related
Working with all the dictionaries within ASP.NET MVC (like RouteData, DataTokens etc), I often find myself wanting to do stuff like:
bool isLolCat = routeData["isLolcat"] as bool
that would return the casted value, or default (false in this case) when the value is null.
Is there any short, readable, simple way to do this, or am I better off writing a helper extension method?
An extension method would something like this.
bool isLolCat = routeData["isLolcat"].TryCast<bool>();
I rather don't want to reinvent the wheel with custom syntax if there is a common way to do this.
I don't want to litter my code with a few lines, when I just to try to get a bool out of a dictionary.
Maybe you like any of these:
(routeData["isLolcat"] as bool?).GetValueOrDefault()
(routeData["isLolcat"] as bool?).GetValueOrDefault(false)
(routeData["isLolcat"] as bool?) ?? false
If not you'll have to write a helper. I actually recommend using a helper because the code that I posted kind of obfuscates what you mean. I'd rather see this:
routeData.GetOrDefault<bool>("isLolcat")
Because this documents in writing what you intend.
Is there any short, readable, simple way to do this, or am I better off writing a helper extension method?
I'd say you would be better writing your own extension because you can make your intentions clear
public static class Ext
{
public static T CastOrDefault<T>(this object obj)
{
return obj is T ? (T)obj : default(T);
}
}
...
bool isLolCat = RouteData["isLolCat"].CastOrDefault<bool>();
Suggestion - If you wanted to keep it short, you could call it something like As<T>
bool isLolCat = RouteData["isLolCat"].As<bool>();
string str = RouteData["isLolCat"].As<string>(); // null
I don't think there's a most common way, all casting / conversion operations have their own idiosyncrasies.
For example, Convert.ToBool can accept strings to convert, do you want this to convert, or should this fail?
x as bool will give you null if it's not of type bool.
I think it would be best to write an extension method for RouteData.
public static T GetValueOrDefault<T>(this RouteData routeData, string field)
{
var value = routeData[field];
if (value is T)
{
return (T)value;
}
return default(T);
}
This way you're operating on the RouteData class and not potentially null values.
Usage:
var isLolCat = routeData.GetValueOrDefault<bool>("IsLolCat");
I have the following statement:
serverCard.Details = !String.IsNullOrEmpty(card.Details) ? card.Details : serverCard.Details;
I want to check and see if card.Details is null or empty... if not, write the value. Is there any syntax that allows me to leave out the else conditional?
Sure, just use a regular if:
if(!String.IsNullOrEmpty(card.Details))
serverCard.Details = card.Details
You can always use the old if statement:
if(!String.IsNullOrEmpty(card.Details))
{
serverCard.Details = card.Details;
}
I think the ternary operator is not needed here.
You can write an extension method for String to check if nullOrEmpty. The regular if then would be shorter
Extension Method:
public static bool IsNullOrEmpty(this string str)
{
return string.IsNullOrEmpty(str);
}
public static bool IsNullOrWhiteSpace(this string str)
{
return string.IsNullOrWhiteSpace(str);
}
The if:
if(!card.Details.IsNullOrWhiteSpace())
serverCard.Details = card.Details
The extension method will work for every string.
I have a simple extension method for string class which will strip all non numeric characters from a string. So if I have a string like for example a phone number such as "(555) 215-4444" it will convert it to "5552154444". It looks like this:
public static string ToDigitsOnly(this string input)
{
Regex digitsOnly = new Regex(#"[^\d]");
return digitsOnly.Replace(input, String.Empty);
}
I am just wondering what is the most elegant way to handle a null value here? Is there a typical pattern to follow in these cases, such as return back a null value if a null is passed in? It seems since I'm extending the string class here I may want to allow null values and not throw a arguement exception (since I'm not really passing in an arguement when I use this...) ? But some might argue I should throw an exception like a 'normal' method would. What's the best practice you are using here?
Thanks!
You can follow the principle of least surprise: use pattern implemented in LINQ:
public static string ToDigitsOnly(this string input)
{
if(input == null)
throw new ArgumentNullException("input");
Regex digitsOnly = new Regex(#"[^\d]");
return digitsOnly.Replace(input, String.Empty);
}
You can use method, proposed by Jon Skeet. It will reduce your check simply to
input.ThrowIfNull("input");
Also Jon has a good section 10.2.4 Calling a method on a null reference in C# in Depth, quote:
CHECKING FOR NULLITY As a conscientious developer, I’m sure that your
production methods always check their arguments’ validity before
proceeding. One question that naturally arises from this quirky
feature of extension methods is what exception to throw when the first
argument is null (assuming it’s not meant to be). Should it be
ArgumentNullException, as if it were a normal argument, or should it
be NullReferenceException, which is what would’ve happened if the
extension method had been an instance method to start with? I
recommend the former: it’s still an argument, even if the extension
method syntax doesn’t make that obvious.
I see this recommendation as (and from my personal experience): it's always better to check for null, specially for static methods and do not to rely on null values. One exception only if it is the exact purpose of your method, for example ThrowIfNull or IsNullOrEmpty extension methods.
It doesn't really matter as long as you communicate the behavior well (so that the end-user knows what to expect).
Consider using the built-in XML Documentation Comments to communicate expected behavior.
/// <exception cref="ArgumentNullException">argument is null.</exception>
public string Example( string argument )
{
if ( argument == null )
throw new ArgumentNullException();
return argument.ToString();
}
See MSDN documentation for many examples:
DateTime.ParseExact Method (String, String, IFormatProvider)
Uri.FromHex Method
Suppose I have this:
class A
{
public void F()
{
//do stuff
}
}
If I then run the following code, what happens?
A a = null;
a.F();
You get a NullReferenceException. So I would say the proper way to write an equivalent extension method would be as follows.
class A
{
}
static class AExtensions
{
void F(this A a)
{
if (a == null)
{
throw new NullReferenceException();
}
//do stuff
}
}
However, .NET disagrees with me on this. The standard in .NET is to instead throw an ArgumentException - so it's probably best to do that instead.
Simple ; Create another method for String , say IsInValid()
public static bool IsInValid(this string s)
{
return (s == null) || (s.Length == 0);
}
use whereever you wanna check...
Furthermore, you can use this extension anywhere
Is it possible to use indexers with extension methods.
eg. Consider it as an example only.
public static object SelectedValue(this DataGridView dgv, string ColumnName)
{
return dgv.SelectedRows[0].Cells[ColumnName].Value;
}
EDIT
usage mygrid.SelectedValue("mycol")
How to use it as an indexer mygrid.SelectedValue["mycol"] rather than above one.
Is it possible to use it like this as well ? mygrid.SelectedValue["mycol"](out somevalue);
What are the syntax of getting this kind of values. Any simple example or link will work.
Well, there are two issues here:
C# doesn't (by and large) support named indexers1
C# doesn't support extension properties, so you can't make SelectedValue a property returning something indexable instead
So no, the syntax you've specified there won't work. You could get this to work:
mygrid.SelectedValue()["mycol"]
but that's a bit ugly. I'd stick with the method form if I were you.
1 C# 4 supports calling named indexers on COM objects.
Let me try to clarify the usage and intentions of Extension Method.
Consider a Extension Method
public static bool IsNullOrEmpty(this string source)
{
return source == null || source == string.Empty;
}
Now you extend your string class with this Extension Method
var myString = "Hello World";
Assert.AreEqual(myString.IsNullOrEmpty(), false);
This is what .NET does on compilation:
public static bool IsNullOrEmpty(string source)
{
return source == null || source == string.Empty;
}
Using our old school
var myString = "Hello World";
Assert.AreEqual(IsNullOrEmpty(myString), false);
Extension method is nothing but a visualization to what we were used to do.
Well, extending indexers could be possible but Microsoft did not think about it.
What's the best way of writing robust code so that a variable can be checked for null and blank.
e.g.
string a;
if((a != null) && (a.Length() > 0))
{
//do some thing with a
}
For strings, there is
if (String.IsNullOrEmpty(a))
You can define an extension method to allow you to do this on many things:
static public bool IsNullOrEmpty<T>(this IEnumerable <T>input)
{
return input == null || input.Count() == 0;
}
It already exists as a static method on the System.String class for strings, as has been pointed out.
And if you are using .NET 4.0 you might want to take a look at String.IsNullOrWhiteSpace.
From version 2.0 you can use IsNullOrEmpty.
string a;
...
if (string.IsNullOrEmpty(a)) ...
if(string.IsNullOrEmpty(string name))
{
/// write ur code
}
for strings:
string a;
if(!String.IsNullOrEmpty(a))
{
//do something with a
}
for specific types you could create an extention method
note that i've used HasValue instead of IsNullorEmpty because 99% of the times you will have to use the !-operator if you use IsNullOrEmpty which I find quite unreadable
public static bool HasValue(this MyType value)
{
//do some testing to see if your specific type is considered filled
}
I find Apache Commons.Lang StringUtils (Java)'s naming a lot easier: isEmpty() checks for null or empty string, isBlank() checks for null, empty string, or whitespace-only. isNullOrEmpty might be more descriptive, but empty and null is, in most cases you use it, the same thing.