I am tired of writing:
if(objectA!=null)
return;
or:
if(objectB==null)
return;
So I was hope to shorten this snippet, to something like this:
Returns.IfNull(objectA);
it is pretty match the same length but usually there are few objects to check and adding params as parameter can shorten:
if(objectA==null || objectB!=null || objectC!=null)
return;
to:
Returns.IfNull(objectA,objectB,objectC);
Basically function IfNull have to get access to function one step higher in stack trace and finish it. But that's only idea, I don't know if it's even possible. Can I find simililar logic in some lib?
No, you are essentially asking the function to exit the function higher than itself which isn't desirable nor really possible unless you throw an exception (which isn't returning per se).
So, you can either do your simple and concise if-null-return checks, or what you may want to do there instead is to throw a well defined exception, but I don't recommend exceptions for flow-control. If these are exceptional (error) circumstances, though, then consider throwing an ArgumentNullException() and handling it as appropriate.
You could write some helper methods to throw ArgumentNullException() for you, of course, to clean it up a bit:
public static class ArgumentHelper
{
public static void VerifyNotNull(object theObject)
{
if (theObject == null)
{
throw new ArgumentNullException();
}
}
public static void VerifyNotNull(params object[] theObjects)
{
if (theObjects.Any(o => o == null))
{
throw new ArgumentNullException();
}
}
}
Then you could write:
public void SomeMethod(object obj1, object obj2, object obj3)
{
ArgumentHelper.VerifyNotNull(obj1, obj2, obj3);
// if we get here we are good!
}
But once again, this is exceptions and not a "return" of the previous method in the stack, which isn't directly possible.
You are asking for something that only the language designer can fix for you.
I have proposed one thing by myself.
The .? operator does return from the current method with the default return value when the argument left to it is null.
return appSettings.?GetElementKey(key).?Value ?? "";
Perhaps we will see it some day in C# 6?
To do similar comparison checks I once defined the following extension method:
/// <summary>
/// Returns whether the object equals any of the given values.
/// </summary>
/// <param name = "source">The source for this extension method.</param>
/// <param name = "toCompare">The objects to compare with.</param>
/// <returns>
/// True when the object equals any of the passed objects, false otherwise.
/// </returns>
public static bool EqualsAny( this object source, params object[] toCompare )
{
return toCompare.Any( o => o.Equals( source ) );
}
It can simplify redundant checks, e.g.:
string someString = "bleh";
bool anyEquals = someString.EqualsAny( "bleh", "bloeh" );
In your case where you check for multiple null checks you could use it as follows:
if ( EqualsAny( null, objectA, objectB, objectX ) ) return;
On another note, your code reminds me of Code Contracts which allows you to define pre and post conditions. In case this is your scenario - perhaps not as I don't see why you call return - it might interest you. Part of it is available for free in .NET 4.0.
You can not invoke another method and expect it to return to the callee of the current method (you could if we had something like continuation passing style; alas, we do not).
You could say:
if(new[] { objectA, objectB, objectC }.Any(x => x != null)) {
return;
}
Or:
if(new[] { objectA, objectB, objectC }.AnyAreNotNull()) {
return;
}
Here, AnyAreNotNull is:
public static class EnumerableExtensions {
public static bool AnyAreNotNull<T>(this IEnumerable<T> source) {
Contract.Requires(source != null);
return source.Any(x => x != null);
}
}
But really, there is nothing wrong with just writing the usual code for this situation.
No, a method can't return the method above it.
Best you could do is create a method that returned true if any of its params were null, then do if (ReturnHelper.AllNull(obj1, obj2, obj3)) return; but i'd say this is much less readable.
Related
I have a few pages, each with a property named Data. On another page I'm setting this data like this:
if (MyPage1 != null)
MyPage1.Data = this.data;
if (MyPage2 != null)
MyPage2.Data = this.data;
if (MyPage3 != null)
MyPage3.Data = this.data;
Is there any possibility to use the null-conditional operator on MyPage? I'm thinking of something like this:
MyPage?.Data = this.data;
But when I write it like this, I get the following error:
The left-hand side of an assignment must be a variable, property or indexer.
I know it's because MyPage could be null and the left-hand side wouldn't be a variable anymore.
It's not that I cannot use it like I have it already but I just want to know if there's any possibility to use the null-conditional operator on this.
The null propagation operator returns a value. And since you must have a variable on the left hand side of an assignment, and not a value, you cannot use it in this way.
Sure, you could make things shorter by using the tenary operator, but that, on the other hand, doesn't really help the readability aspect.
Joachim Isaksson's comment on your question shows a different approach that should work.
As Joachim Isaksson suggested in the comments, I now have a method SetData(Data data) and use it like this:
MyPage1?.SetData(this.data);
MyPage2?.SetData(this.data);
MyPage3?.SetData(this.data);
I came up with the following extension,
public static class ObjectExtensions
{
public static void SetValue<TValue>(this object #object, string propertyName, TValue value)
{
var property = #object.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
if (property?.CanWrite == true)
property.SetValue(#object, value, null);
}
}
Which may be called globally; this only works on public properties.
myObject?.SetValue("MyProperty", new SomeObject());
The following improved version works on anything,
public static void SetValue<TObject>(this TObject #object, Action<TObject> assignment)
{
assignment(#object);
}
And may also be called globally,
myObject?.SetValue(i => i.MyProperty = new SomeObject());
But the extension name is somewhat misleading as the Action does not exclusively require an assignment.
Rather late to the party, but I came to this article with a similar issue. I took the idea of the SetValue method and created a generic extension method, as below:
/// <summary>
/// Similar to save navigation operator, but for assignment. Useful for += and -= event handlers.
/// If <paramref name="obj"/> is null, then <paramref name="action"/> is not performed and false is returned.
/// If <paramref name="obj"/> is not null, then <paramref name="action"/> is performed and true is returned.
/// </summary>
public static bool SafeAssign<T>(this T obj , Action<T> action ) where T : class
{
if (obj is null) return false;
action.Invoke(obj);
return true;
}
Example usage, for attaching and detaching event an handler:
public void Attach() => _control.SafeAssign(c => c.MouseDown += Drag);
public void Detach() => _control.SafeAssign(c => c.MouseDown-= Drag);
Hope somebody finds it useful :)
Try this
Add all your pages to myPageList.
IEnumerable<MyPage> myPageList;
foreach(MyPage myPage in myPageList)
{
if (myPage != null)
myPage.Data = this.data;
}
You can Use Extension Method
public static void NCC<T>(this T instance, System.Action<T> func)
where T : class
{
if (instance != null)
{
func(instance);
}
}
MyPage1.NCC(_=>_.Data = this.data);
A generic SetValue extension method (but only for ref properties) would be:
public static void SetValue<T>(this T property, T value)
{
property = value;
}
And will be used like
ButtonOrNull?.Visibility.SetValue(Visibility.Hidden);
I know this is most probably a simple question involving Generics, or, quite possibly, just a big "no-no" overall, but I'm curious to see if I can get this working.
I'm trying to create a method that takes in an object and, if the object is an enumerable type, to pass it off to a method that can work on any kind of enumerable, but I'm getting terribly stuck.
My current code for the method that takes in an object looks something like the following:
private void MyMethod()
{
Dictionary<string, object> MyVals = new Dictionary<string,object>();
... fill the MyVals dictionary ...
object x = MyVals["Val_1"];
Type type = x.GetType();
// Check if we have a series of values rather than a single value
if (type != typeof(string) && typeof(IEnumerable).IsAssignableFrom(type))
Test(x);
}
Then, I thought I could write something like one of the following as the method signature for my Test method:
1. Write it as if it's an IEnumerable of object:
private void Test(IEnumerable<object> MyEnumeration)
Tried calling it via:
Test((IEnumerable<object>)x);
Leads to run-time error that it cannot cast from IEnumerable<int> to IEnumerable<object>
2. Try using Generics:
private void Test<T>(IEnumerable<T> MyEnumeration)
Tried calling it via:
Test(x);
Leads to design-time error that the signature is incorrect / invalid arguments.
or via:
Test<type>(x);
Leads to a design-time error that the type or namespace type could not be found.
How could this be done OR is it just bad programming practice and there is a better way to do this?
Thanks!
The problem is with this code:
if (type != typeof(string) && typeof(IEnumerable).IsAssignableFrom(type))
Test(x);
You now know that x is an IEnumerable, but it still treated as an object when the compiler determines which method signatures are compatible.
If you did this:
if (type != typeof(string) && typeof(IEnumerable).IsAssignableFrom(type))
{
IEnumerable asEnumerable = (IEnumerable)x;
Test(asEnumerable);
}
Then it can be passed to
void Test(IEnumerable t)
{
}
Or, if you really want to use IEnumerable<object>:
if (type != typeof(string) && typeof(IEnumerable).IsAssignableFrom(type))
{
IEnumerable<object> asEnumerable = ((IEnumerable)x).Cast<object>();
Test(asEnumerable);
}
And, if you want an IEnumerable<T>, see Jon Skeet's answer to a different question.
You should create two overloads of Test() method. one which would handle IEnumerable and another which handles IEnumerable<T>. Why do you need method overload? Because IEnumerables are not generic IEnumerable<T> and at run time you won't be knowing the type of generic type to use Cast on object.
Below is the sample showing how exactly you can achieve what you're looking for:
public void MyMethod()
{
// Sample object with underlying type as IEnumerable
object obj1 = new ArrayList();
// Sample object with underlying type as IEnumerable & IEnumerable<T>
object obj2 = (IList<string>)new List<string>();
if (typeof(IEnumerable).IsAssignableFrom(obj1.GetType()))
{
if (!obj1.GetType().IsGenericType)
{
// Handles case of IEnumerable
Test((IEnumerable)obj1);
}
else
{
// Handles case of IEnumerable<T>
InvokeGenericTest(obj2);
}
}
}
public void Test(IEnumerable source)
{
Console.WriteLine("Yes it was IEnumerable.");
}
public void Test<T>(IEnumerable<T> source)
{
Console.WriteLine("Yes it was IEnumerable<{0}>.", typeof(T));
// Use linq with out worries.
source.ToList().ForEach(x => Console.WriteLine(x));
}
/// <summary>
/// Invokes the generic overload of Test method.
/// </summary>
/// <param name="source"></param>
private void InvokeGenericTest(object source)
{
Type t = source.GetType();
var method = this.GetType().GetMethods().Where(x => x.IsGenericMethod && x.Name == "Test").First();
var genericMethod = method.MakeGenericMethod(t.GenericTypeArguments.First());
genericMethod.Invoke(this, new object[] { source });
}
This has a bad code smell so I would elaborate what it is you actually want to do and maybe someone can help. Your runtime error is due to the fact the collection you have is in fact NOT an IEnumerable[object] but is IEnumerable[int]. You would have to call .Cast<object> first.
So it would be a double cast.
Test(((IEnumerable<int>)x).Cast<object>);
Again, this has a terrible code smell. You should elaborate how the data is coming in and I am sure someone can help you.
Let's suppose we want to throw if we try to assign null to something, what about this trick:
public static class ExceptionExtension
{
public static T Throw<T>(this Exception exc)
{
throw exc;
}
}
that we can use for example like this:
return possibleNull ?? new Exception("Unspecified something....").Throw<string>();
do you think it is a good/worst/useless practice ?
It makes no sense to me - not very readable. I would expect the second argument of the ?? operator to be of the same type of possibleNull, not to throw an excpetion.
I would much rather see:
if(possibleNull == null)
{
throw new Exception("Unspecified something....");
}
return possibleNull;
It could be better and more readable to create some kind of static helper class that throws
Like this
public static class ThrowHelper
{
public static TException ThrowIfNull<TException>(object value)
where TException : Exception, new()
{
if (value == null) //or other checks
{
throw new TException();
}
}
}
You could always stick it in some sort of short-named static helper class:
public static class Never
{
public static T Null<T>(T value)
where T : class
{
if (value == null) throw new ArgumentNullException();
return value;
}
}
myClass.AProperty = Never.Null(somePotentiallyNullValue);
Your other example wouldn't make much sense, I'd opt for calling it "useless" practice.
Adding a bit of "fluency" to helper classes tends to focus on making things more readable.
http://en.wikipedia.org/wiki/Fluent_interface
I wouldn't consider it a good practice.
First, the extension method itself just introduces a method for something we already have a keyword for: throw. This might be confusing. It declares a return type though it will never return a value, just to please the compiler in the context where you want to use it. Referring to what others already pointed out, that's rather a "principle of most astonishment".
Then, looking on how you would employ this method, the resulting code seems not very clear to read. Even worse: you can only use this approach in an expression, so you would always end up with code that uses an object in some way (in your example: just return it) and checks it for null as a side effect in the same line. I'd prefer doing null checks explicitly and not mixed with something else. A library like CuttingEdge.Conditions can help to reduce the amount of code you have to type for this. You would use it in your example this way
Condition.Requires(possibleNull , "possibleNull ").IsNotNull();
return possibleNull;
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Finding the Variable Name passed to a Function in C#
In C#, is there a way (terser the better) to resolve the name of a parameter at runtime?
For example, in the following method, if you renamed the method parameter, you'd also have to remember to update the string literal passed to ArgumentNullException.
public void Woof(object resource)
{
if (resource == null)
{
throw new ArgumentNullException("resource");
}
// ..
}
One way:
static void Main(string[] args)
{
Console.WriteLine("Name is '{0}'", GetName(new {args}));
Console.ReadLine();
}
This code also requires a supporting function:
static string GetName<T>(T item) where T : class
{
var properties = typeof(T).GetProperties();
Enforce.That(properties.Length == 1);
return properties[0].Name;
}
Basically the code works by defining a new Anonymous Type with a single Property consisting of the parameter who's name you want. GetName() then uses reflection to extract the name of that Property.
There are more details here: http://abdullin.com/journal/2008/12/13/how-to-find-out-variable-or-parameter-name-in-c.html
Short answer: No, there isn't. (Is that terse enough? ;)
(EDIT: Justin's answer probably counts. It leaves a bad taste in my mouth, but it accomplishes the goal of "no need to put the parameter name into a string". I don't think I'd really count AOP though, as that's really changing to a completely different approach rather than answering the original question of getting a parameter name from within a method.)
Longer answer: There's a way to find out all the parameters of a method, but I don't think it's useful in this case.
Here's an example which displays the parameter names from a couple of methods:
using System;
using System.Reflection;
class Test
{
static void Main()
{
Foo(null);
Bar(null);
}
static void Foo(object resource)
{
PrintParameters(MethodBase.GetCurrentMethod());
}
static void Bar(object other)
{
PrintParameters(MethodBase.GetCurrentMethod());
}
static void PrintParameters(MethodBase method)
{
Console.WriteLine("{0}:", method.Name);
foreach (ParameterInfo parameter in method.GetParameters())
{
Console.WriteLine(" {0} {1}",
parameter.ParameterType,
parameter.Name);
}
}
}
So that does that, but if you have multiple parameters and you wanted to throw an appropriate exception, how would you know (in a safe way) which to use? Ideally you want something like:
public void Woof(object resource)
{
if (resource == null)
{
throw new ArgumentNullException(infoof(resource));
}
// ..
}
where the mythical infoof operator would return a ParameterInfo. Unfortunately this doesn't exist.
I dealt with this very same issue. There are a couple of ways of getting the parameter name but the most performant is to dip down into the IL. You can see an example of my implementation on my blog post on this very issue Taking the pain out of parameter validation.
The one caveat to this approach is you need to pass the parameter name in as a delegate but it is small price to pay for cleaner code:
public void SomeMethod(string value)
{
Validate.Argument(() => value).IsNotNull().IsNotEmpty();
}
Which is somewhat cleaner and clearer than:
public void SomeMethod(string value)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
if (value == string.Empty)
{
throw new ArgumentException("Value cannot be an empty string.", "value");
}
}
The static method approach has allowed me to chain a number of methods together in a fluent interface. Initially an Argument object is returned which only allows a basic null test which returns a ReferenceArgument object which can then have additional validation. If the object under test is a value type then different tests are available.
The API allows for a number of common tests but it would be hard to capture all the possible tests so to provide flexibility a generic test method allows an expression or function to be provided and in the case of the former the expression can actually be used as the error message.
My example only covers a few of the basics but you can easily expand the interface to check for ranges and throw ArgumentOutOfRangeExceptions or test objects inherit from a specific base class or implement an interface. There are some similar implementations but I have not as yet seen any that get the parameter name.
You can get this information using AOP. You can define an intercept that is invoked before method execution and throw the exception there. This also takes care of the problem that null checking is a cross-cutting concern.
PostSharp is a good simple implementation of AOP.
Here's what your code would look like (haven't tested, but it should get you very close)
[AttributeUsage(AttributeTargets.Parameter)]
public class CanBeNullAttribute : Attribute
{
private readonly bool canBeNull;
public CanBeNullAttribute()
: this(true)
{
}
public CanBeNullAttribute(bool canBeNull)
{
this.canBeNull = canBeNull;
}
public bool AllowNull
{
get { return canBeNull; }
}
}
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class EnforceNullConstraintAttribute : OnMethodInvocationAspect
{
public override void OnInvocation(MethodInvocationEventArgs eventArgs)
{
object[] arguments = eventArgs.GetArgumentArray();
ParameterInfo[] parameters = eventArgs.Delegate.Method.GetParameters();
for (int i = 0; i < arguments.Length; i++)
{
if (arguments[i] != null) continue;
foreach (CanBeNullAttribute attribute in parameters[i].GetCustomAttributes(typeof(CanBeNullAttribute), true))
{
if (!attribute.AllowNull) throw new ArgumentNullException(parameters[i].Name);
}
}
base.OnInvocation(eventArgs);
}
}
Now, you can modify your method:
[EnforceNullConstraint]
public void Woof([CanBeNull(false)] object resource)
{
// no need to check for null, PostSharp will weave it at compile time
// execute logic assured that "resource" is not null
}
You might want:
1)
public static void ThrowIfNull<T>(Expression<Func<T>> expr)
{
if (expr == null || expr.Compile()() != null) //the compile part is slow
return;
throw new ArgumentNullException(((MemberExpression)expr.Body).Member.Name);
}
or
2)
public static void ThrowIfNull<T>(Expression<Func<T>> expr)
{
if (expr == null)
return;
var param = (MemberExpression)expr.Body;
if (((FieldInfo)param.Member).GetValue(((ConstantExpression)param.Expression).Value) == null)
throw new ArgumentNullException(param.Member.Name);
}
And call it:
Class.ThrowIfNull(() => resource);
But that's not what you would want probably. Its also a lot slower 1) is abt 1000 times slower than 2). May be:
3)
public static void ThrowIfNull<T>(this T item) where T : class
{
if (item == null)
return;
var param = typeof(T).GetProperties()[0];
if (param.GetValue(item, null) == null)
throw new ArgumentNullException(param.Name);
}
And call it:
new { resource }.ThrowIfNull();
Cleaner, much faster than above 2! :)
You can also extend these methods for properties of objects. For eg.,
new { myClass.MyProperty1 }.ThrowIfNull();
You can cache property values to improve performance further as property names don't change during runtime. See related question Finding the variable name passed to a function
I want to determine if a generic object type ("T") method type parameter is a collection type. I would typically be sending T through as a Generic.List but it could be any collection type as this is used in a helper function.
Would I be best to test if it implements IEnumerable<T>?
If so, what would the code look like?
Update 14:17 GMT+10 Possibly extending on a solution here (however only works for List<T>'s not IEnumerable<T>'s when it should if List derives ?)
T currentObj;
// works if currentObj is List<T>
currentObj.GetType().GetGenericTypeDefinition() == typeof(List<>)
// does not work if currentObj is List<T>
currentObj.GetType().GetGenericTypeDefinition() == typeof(IEnumerable<>)
This will be the simplest check..
if(Obj is ICollection)
{
//Derived from ICollection
}
else
{
//Not Derived from ICollection
}
You can use Type.GetInterface() with the mangled name.
private bool IsTAnEnumerable<T>(T x)
{
return null != typeof(T).GetInterface("IEnumerable`1");
}
In order to get the actual type of T at runtime, you can use the typeof(T) expression. From there the normal type comparison operators will do the trick
bool isEnumerable = typeof(IEnumerable<int>).IsAssignableFrom(typeof(T));
Full Code Sample:
static bool Foo<T>()
{
return typeof(IEnumerable<int>).IsAssignableFrom(typeof(T));
}
Foo<List<T>>(); // true
Foo<int>(); // false
Personally I tend to use a method that I wrote myself, called TryGetInterfaceGenericParameters, which I posted below. Here is how to use it in your case:
Example of use
object currentObj = ...; // get the object
Type[] typeArguments;
if (currentObj.GetType().TryGetInterfaceGenericParameters(typeof(IEnumerable<>), out typeArguments))
{
var innerType = typeArguments[0];
// currentObj implements IEnumerable<innerType>
}
else
{
// The type does not implement IEnumerable<T> for any T
}
It is important to note here that you pass in typeof(IEnumerable<>), not typeof(IEnumerable) (which is an entirely different type) and also not typeof(IEnumerable<T>) for any T (if you already know the T, you don’t need this method). Of course this works with any generic interface, e.g. you can use typeof(IDictionary<,>) as well (but not typeof(IDictionary)).
Method source
/// <summary>
/// Determines whether the current type is or implements the specified generic interface, and determines that
/// interface's generic type parameters.</summary>
/// <param name="type">
/// The current type.</param>
/// <param name="interface">
/// A generic type definition for an interface, e.g. typeof(ICollection<>) or typeof(IDictionary<,>).</param>
/// <param name="typeParameters">
/// Will receive an array containing the generic type parameters of the interface.</param>
/// <returns>
/// True if the current type is or implements the specified generic interface.</returns>
public static bool TryGetInterfaceGenericParameters(this Type type, Type #interface, out Type[] typeParameters)
{
typeParameters = null;
if (type.IsGenericType && type.GetGenericTypeDefinition() == #interface)
{
typeParameters = type.GetGenericArguments();
return true;
}
var implements = type.FindInterfaces((ty, obj) => ty.IsGenericType && ty.GetGenericTypeDefinition() == #interface, null).FirstOrDefault();
if (implements == null)
return false;
typeParameters = implements.GetGenericArguments();
return true;
}
Also, remember just because you are using generics, don't forget other basic techniques, in this case, like overloading. I suspect the you are planning something like this:
void SomeFunc<T>(T t)
{
if (IsCollectionCase(t))
DoSomethingForCollections()
else
DoSOmethingElse();
}
This would be far better handled as:
void SomeFunc(IEnumerable t)
{
DoSomethingForCollections()
}
void SomeFunc<T>(T t)
{
DoSomethingElse()
}
I would test IEnumerable instead, since a collection type could implement only IEnumerable, it doesn't have to implement IEnumerable<T>.
It also depends: what do you mean with collection type? You could have a collection without implementing any of those interfaces.
While I can't be certain what the original poster's intent was, there have been several responses to the effect of casting to IEnumerable for testing. That's fine, but everyone should be aware that string instances pass this test, which may not be something the original author intended. I know I certainly didn't when I went looking for an answer and found this post:
string testString = "Test";
Console.WriteLine(testString as IEnumerable != null); // returns true
I am in the process of trying to write a custom serializer that uses reflection to accomplish certain tasks. As part of a task, I need to determine if a property value is a collection/array/list of items or a single property value. What is particularly annoying is that several Linq expressions actually result in an enumerable type value, but GetType().IsArray returns false for these, and casting them to ICollection returns null as well, but casting them to IEnumerable returns a non-null value.
So...for the time being, I am still seeking a solution that works for all cases.
For simplicity and code sharing, I usually use this extension method:
public static bool IsGenericList(this object obj)
{
return IsGenericList(obj.GetType());
}
public static bool IsGenericList(this Type type)
{
if (type == null)
{
throw new ArgumentNullException("type");
}
foreach (Type #interface in type.GetInterfaces())
{
if (#interface.IsGenericType)
{
if (#interface.GetGenericTypeDefinition() == typeof(ICollection<>))
{
// if needed, you can also return the type used as generic argument
return true;
}
}
}
return (type.GetInterface("IEnumerable") != null);
}
If you want to do a check and get true for any list/collection/IEnumerable, but get false for type of string, then
private static bool IsIEnumerable(Type requestType)
{
var isIEnumerable = typeof(IEnumerable).IsAssignableFrom(requestType);
var notString = !typeof(string).IsAssignableFrom(requestType);
return isIEnumerable && notString;
}
I came across the same issue while attempting to serialize any object to JSON format. Here is what I ended up using:
Type typ = value.GetType();
// Check for array type
if(typeof(IEnumerable).IsAssignableFrom(typ) || typeof(IEnumerable<>).IsAssignableFrom(typ))
{
List<object> list = ((IEnumerable)value).Cast<object>().ToList();
//Serialize as an array with each item in the list...
}
else
{
//Serialize as object or value type...
}
I love generics. In this method T must have a public and parameterless constructor which means you can not use IList<object> for T. You must use List<object>
public static T IsEnumerable<T>() where T : new() {
if (new T() is IEnumerable) {
}
For an ICollection of any type (List or HashSet for example):
internal static bool IsCollection(this Type type) => type.GetGenericArguments().Length > 0 && (typeof(ICollection<>).MakeGenericType(type.GetGenericArguments()[0])).IsAssignableFrom(type);