Extension method to compare two objects for unit testing - c#

I want to write an extension methods for compare some proprties of two objects. I wrote this code:
public static void AreTwoObjectsEqual(this Assert asr, object Actual, object Expected, List<string> FieldsMustCheck)
{
foreach (string item in FieldsMustCheck)
{
if (Actual.GetType().GetProperty(item) == null || Expected.GetType().GetProperty(item) == null)
{
throw new Exception("Property with name : " + item + " not found in objects ");
}
var ActualPropertyValue = Actual.GetType().GetProperty(item).GetValue(Actual, null);
var ExpectedPropertyValue = Expected.GetType().GetProperty(item).GetValue(Expected, null);
if (ActualPropertyValue != ExpectedPropertyValue)
{
throw new AssertFailedException("Test failed for propery : " + item);
}
}
}
when I want to build the project I get this error:
'Microsoft.VisualStudio.TestTools.UnitTesting.Assert': static types cannot be used as parameters
Can any one help me remove this error.Thanks

Well the compiler error message is fairly clear: Assert is a static class, so you can't use that as the parameter type for the extension method. It's not clear why you wanted to in the first place, to be honest. If you were hoping to be able to use Assert.AreTwoObjectsEqual, you just can't do that - extension methods are meant to mimic instance methods, not static methods in a different type.
I suspect you should just create a static class of your own, e.g. MoreAssert, and just make it a normal static method:
public static class MoreAssert
{
public static void AreEqualByProperties(object expected, object actual,
List<string> propertyNames)
{
...
}
}
Parameter names changed to comply with .NET naming conventions. I'd strongly encourage you to use camelCase names for local variables, too. I've also reordered the parameters to be consistent with the other assertions.
So then you'd just call:
MoreAssert.AreEqualByProperties(...);
You might also consider using params string[] propertyNames instead of List<string> propertyNames to make it easier to call.

Related

how to check whether a variable is a class or not in c#

I have a function that gets a object as a parameter
ex:
public static void doSomthingWithObject(object obj)
{
(.....)
}
and I want to check whether the object I got is a class or a simple variable (e.g if it requires a constructor to create) and if so, I want to get all the properties of that object so the code will look something like that:
public static void doSomthingWithObject(object obj)
{
if(objectIsClass())
{
object[] arr = obj.getAllPropeties
(.....)
}
else
{
(.....)
}
}
is that possible?
edit:
people found my definition to class variables and simple variables confusing. to make it clear, "simple variable" is a variable that can hold only one value, and to access this value you need to simply write "= var" while "class variable" can hold multiple values (unless it has 1-0 properties), and each one of its values can be accessed using get ex: = obj.prop (unless there is no get) each value in this type of variable is held by a property, and to define a new class property the new keyword must be used
In C#, everything that you see is either a class or a struct, (Int is struct for example).
So the question comes down to two things,
Do you want to know all the types which do not have a parameterless constructor (like int doesn't have)
To do that,
bool ObjectIsClass(object o)
{
return o.GetType().GetConstructor(new Type[0])!=null;
}
Do you want to Look for Primitive types
bool IsPrimitive(object o)
{
return o.GetType().IsPrimitive;
}
I think this should do it:
public static void DoSomthingWithObject(Object obj)
{
if (!obj.GetType().IsPrimitive)
{
Console.WriteLine("This is a class.");
var properties = obj.GetType().GetProperties();
foreach (var p in properties) {
Console.WriteLine(p);
}
}
else
{
Console.WriteLine("This is NOT a class.");
}
}
Not exactly sure what you mean by "get all properties". But this code will check if the indata is an instance of a non-primitive class and give you the name of all the properties. Perhaps it is a start.

How could I achieve JQuery style method calls on IEnumerables in C#?

In JQuery you can write $('.my-class').hide() and it will call hide() on all the results. There's no for loop, no iterating, no LINQ extensions and lambdas etc. and it makes dealing with lists super fun. I want to be able to have this functionality on IEnumerables in C#. I think Matlab has a similarly concise syntax when operating on arrays/matrices.
Long story short, I want the following code (or similar) to work:
class Program
{
static List<MyClass> MyList = new List<MyClass>();
static void Main(string[] args)
{
for (int i = 0; i < 100; i++)
MyList.Add(new MyClass());
MyList.MyMethod();
// should be exactly equivalent to:
MyList.Select(n => n.MyMethod());
}
}
class MyClass
{
public int MyMethod() { return 123; }
}
I'm aware this is possible on a case-by-case basis using extension methods:
public static IEnumerable<int> MyMethod(this IEnumerable<MyClass> lst)
{
return lst.Select(n => n.MyMethod());
}
But we'd have to create one extension method for every single method on every single type that you wanted this behaviour on.
Ideally this would be possible for all types and all methods and still be type-safe at compile time. I suspect I'm asking too much from the C# language here, but how would we do this or something similar in a as-generic-as-possible way?
Possible solutions:
Auto-generate extension methods for particular types. If we only intend to use this notation for a few types, we could just generate the extension methods once automatically. This would achieve the exact syntax and full type safety but generating code would be a pain.
A single extension method that returns a dynamic object built using reflection on the supplied type. The idea is that we'd use reflection to iterate through the type's methods and build up a dynamic object that would have all the methods like .MyMethod() that would behind the scenes call Select(...) on the IEnumerable. The syntax would end up being something like MyList.Selector().MyMethod(). But now we've lost the syntax and type safety. Clever, maybe. Useful, probably not.
Intercepting method calls? Is it possible to decide how to react to a method call at runtime? I don't know. Again you'd lose type safety.
The most simple solution is using dynamic objects. If you are willing to throw away type safety, you can make a IEnumerable type that behaves statically when needed and dynamically otherwise, here's a sample prototype:
public class DynamicIEnumerable<T> : DynamicObject, IEnumerable<T>
{
public IEnumerable<T> _enumerable;
public DynamicIEnumerable(IEnumerable<T> enumerable)
{
this._enumerable = enumerable;
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
result = new DynamicIEnumerable<T>(_enumerable.Select(x => (T)typeof(T).InvokeMember(binder.Name, BindingFlags.InvokeMethod, null, x, null)));
return true;
}
public IEnumerator<T> GetEnumerator()
{
return _enumerable.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _enumerable.GetEnumerator();
}
}
In TryInvokeMember, the invoked member on IENumerable is applied on all items using reflection. The only constraints on this approach is that you have to return this in invoked method. Here's a sample of how to use this approach:
public class SomeClass
{
public int Value {get;set;}
public SomeClass(int value)
{
this.Value = x;
}
public SomeClass Plus10()
{
Value += 10;
return this;
}
}
static void Main()
{
dynamic d = new DynamicIEnumerable<X>(Enumerable.Range(0, 10).Select(x => new SomeClass(x)));
foreach (var res in d.Plus10().Plus10())
Console.WriteLine(res.Value);
}
how would we do this or something similar in a as-generic-as-possible way?
This isn't a pretty solution but it does work:
public class MyClass
{
public void MyMethod()
{
}
public void MyMethod2()
{
}
}
Extension Method:
public static class WeirdExtensions
{
public static IEnumerable<T> CallOnAll<T>(this IEnumerable<T> instance ,
Action<T> call)
{
foreach(var item in instance)
{
call(item);
}
return instance;
}
}
Usage (chaining/fluent):
var blah = new List<MyClass>();
blah.CallOnAll(b => b.MyMethod())
.CallOnAll(b => b.MyMethod2());
Notes
This isn't quite possible due to a the underlying assumption that you'd have to every single method on every single type. In jQuery/Html there is only one underlying type of an Html Element. All elements are exposed to the same methods (whether or not the type supports it). In jQuery, you can call $('head').hide() but it won't do anything visually, but because it is an element, it will be inline styled. If you need a new method, you do have a build one, but for only one type because there is only one type.
In contrast with C# you build your types (many many types) and they all have different methods (sure there could be overlap).

Check if two variables are of the same when the type is dynamic and both variables are the derivatives of same base class

Is it possible to check if the list contains an object of given (but dynamic) type, derrived from same basic abstract class?
The main problem is not about the list, but about comparing types itself.
In single variables and static variables, it's easy:
if(someVariable is int)
Checking the list with static type is also easy, like:
SomeList.OfType<int>().Any()
or
(from _Object in SomeList.OfType<int> where _Object is int select _Object).Count() == 0
but I cant't handle it if the type I want to check is dynamic, f.e. passed as method parameter:
abstract class BasicClass;
class DerivativeOne : BasicClass { }
class DerivativeTwo : BasicClass { }
// in main:
List<BasicClass> _List = new List<BasicClass>();
DerivativeOne a = new DerivativeOne();
DerivativeTwo b = new DerivativeTwo();
DerivativeOne c = new DerivativeOne();
if(!CheckIfTypeExistsInList(a, _List)
{
_List.Add(a);
}
if(!CheckIfTypeExistsInList(b, _List)
{
_List.Add(b);
}
if(!CheckIfTypeExistsInList(c, _List)
{
_List.Add(c); // this is what I don't want to happen,
// because I already have one object of type DerivativeOne in my list.
}
// the function:
bool CheckIfTypeExistsInList(BasicClass pObject, List<BasicClass> pList)
{
/// few attempts:
pList.OfType<(pObject.GetType()>().Any(); // attempt one, error
return (from _Object in SomeList.OfType<(pObject.GetType())> where _Object is int select _Object).Count() == 0; // attempt two, error
}
PS. I am aware that the code doesn't look neat, but I tried to show just the problem itself, skipping extra logic and stuff.
PS2. I am aware that the solution to the problem would be just to put some attribute to BasicClass and make each derivative to have unique value of the attribute, but still - I'm not looking for another route to solve the problem, I'm just interested if it's possible to do it "this" way.
When the type is known only at runtime, you cannot use it in a generic without using reflection. However, your task is simpler than that - you can use type equality to achieve the results that you want:
Type targetType = pObject.GetType();
if (SomeList.Any(o => targetType.Equals(o.GetType()))) {
...
}

C# Extension Method for Object

Is it a good idea to use an extension method on the Object class?
I was wondering if by registering this method if you were incurring a performance penalty as it would be loaded on every object that was loaded in the context.
In addition to another answers:
there would be no performance penalty because extension methods is compiler feature. Consider following code:
public static class MyExtensions
{
public static void MyMethod(this object) { ... }
}
object obj = new object();
obj.MyMethod();
The call to MyMethod will be actually compiled to:
MyExtensions.MyMethod(obj);
There will be no performance penalty as it doesn't attach to every type in the system, it's just available to be called on any type in the system. All that will happen is that the method will show on every single object in intellisense.
The question is: do you really need it to be on object, or can it be more specific. If it needs to be on object, the make it for object.
If you truly intend to extend every object, then doing so is the right thing to do. However, if your extension really only applies to a subset of objects, it should be applied to the highest hierarchical level that is necessary, but no more.
Also, the method will only be available where your namespace is imported.
I have extended Object for a method that attempts to cast to a specified type:
public static T TryCast<T>(this object input)
{
bool success;
return TryCast<T>(input, out success);
}
I also overloaded it to take in a success bool (like TryParse does):
public static T TryCast<T>(this object input, out bool success)
{
success = true;
if(input is T)
return (T)input;
success = false;
return default(T);
}
I have since expanded this to also attempt to parse input (by using ToString and using a converter), but that gets more complicated.
Is it a good idea to use an extension method on the Object class?
Yes, there are cases where it is a great idea in fact.Tthere is no performance penalty whatsoever by using an extension method on the Object class. As long as you don't call this method the performance of your application won't be affected at all.
For example consider the following extension method which lists all properties of a given object and converts it to a dictionary:
public static IDictionary<string, object> ObjectToDictionary(object instance)
{
var dictionary = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
if (instance != null)
{
foreach (var descriptor in TypeDescriptor.GetProperties(instance))
{
object value = descriptor.GetValue(instance);
dictionary.Add(descriptor.Name, value);
}
}
return dictionary;
}
The following example demonstrates the extension method in use.
namespace NamespaceName
{
public static class CommonUtil
{
public static string ListToString(this IList list)
{
StringBuilder result = new StringBuilder("");
if (list.Count > 0)
{
result.Append(list[0].ToString());
for (int i = 1; i < list.Count; i++)
result.AppendFormat(", {0}", list[i].ToString());
}
return result.ToString();
}
}
}
The following example demonstrates how this method can be used.
var _list = DataContextORM.ExecuteQuery<string>("Select name from products").ToList();
string result = _list.ListToString();
This is an old question but I don't see any answers here that try to reuse the existing find function for objects that are active. Here's a succinct extension method with an optional overload for finding inactive objects.
using System.Linq;
namespace UnityEngine {
public static class GameObjectExtensionMethods {
public static GameObject Find(this GameObject gameObject, string name,
bool inactive = false) {
if (inactive)
return Resources.FindObjectsOfTypeAll<GameObject>().Where(
a => a.name == name).FirstOrDefault();
else
return GameObject.Find(name);
}
}
}
If you use this function within the Update method you might consider changing the LINQ statement with an array for loop traversal to eliminate garbage generation.

C# Generics and Casting Issue

I am having trouble casting an object to a generic IList. I have a group of in statements to try to work around this, but there has to be a better way to do this.
This is my current method:
string values;
if (colFilter.Value is IList<int>)
{
values = BuildClause((IList<int>)colFilter.Value, prefix);
}
else if (colFilter.Value is IList<string>)
{
values = BuildClause((IList<string>)colFilter.Value, prefix);
}
else if (colFilter.Value is IList<DateTime>)
{
values = BuildClause((IList<DateTime>)colFilter.Value, prefix);
}
else if (...) //etc.
What I want to do is this:
values = BuildClause((IList<colFilter.ColumnType>)colFilter.Value, prefix);
or
values = BuildClause((IList<typeof(colFilter.ColumnType)>)colFilter.Value, prefix);
or
values = BuildClause((IList<colFilter.ColumnType.GetType()>)colFilter.Value, prefix);
Each of these produces this compiler error:
The type or namespace name 'colFilter' could not be found (are you missing a using directive or an assembly reference?)
In my example, colFilter.ColumnType is int, string, datetime, etc. I am not sure why this does not work.
Any ideas?
EDIT: This is C#2.0
EDIT #2
Here is the BuildClause method (I have overloads for each type):
private static string BuildClause(IList<int> inClause, string strPrefix)
{
return BuildClause(inClause, strPrefix, false);
}
private static string BuildClause(IList<String> inClause, string strPrefix)
{
return BuildClause(inClause, strPrefix, true);
}
private static string BuildClause(IList<DateTime> inClause, string strPrefix)
{
return BuildClause(inClause, strPrefix, true);
}
//.. etc for all types
private static string BuildClause<T>(IList<T> inClause, string strPrefix, bool addSingleQuotes)
{
StringBuilder sb = new StringBuilder();
//Check to make sure inclause has objects
if (inClause.Count > 0)
{
sb.Append(strPrefix);
sb.Append(" IN(");
for (int i = 0; i < inClause.Count; i++)
{
if (addSingleQuotes)
{
sb.AppendFormat("'{0}'", inClause[i].ToString().Replace("'", "''"));
}
else
{
sb.Append(inClause[i].ToString());
}
if (i != inClause.Count - 1)
{
sb.Append(",");
}
}
sb.Append(") ");
}
else
{
throw new Exception("Item count for In() Clause must be greater than 0.");
}
return sb.ToString();
}
There's no way to relate method overloading and generics: although they look similar, they are very different. Specifically, overloading lets you do different things based on the type of arguments used; while generics allows you to do the exact same thing regardless of the type used.
If your BuildClause method is overloaded and every overload is doing something different (not just different by the type used, but really different logic, in this case - choosing whether or not to add quotes) then somewhere, ultimately, you're gonna have to say something like "if type is this do this, if type is that do that" (I call that "switch-on-type").
Another approach is to avoid that "switch-on-type" logic and replace it with polymorphism. Suppose you had a StringColFilter : ColFilter<string> and a IntColFilter : ColFilter<int>, then each of them could override a virtual method from ColFilter<T> and provide its own BuildClause implementation (or just some piece of data that would help BuildClause process it). But then you'd need to explicitly create the correct subtype of ColFilter, which just moves the "switch-on-type" logic to another place in your application. If you're lucky, it'll move that logic to a place in your application where you have the knowledge of which type you're dealing with, and then you could explicitly create different ColFilters at different places in your application and process them generically later on.
Consider something like this:
abstract class ColFilter<T>
{
abstract bool AddSingleQuotes { get; }
List<T> Values { get; }
}
class IntColFilter<T>
{
override bool AddSingleQuotes { get { return false; } }
}
class StringColFilter<T>
{
override bool AddSingleQuotes { get { return true; } }
}
class SomeOtherClass
{
public static string BuildClause<T>(string prefix, ColFilter<T> filter)
{
return BuildClause(prefix, filter.Values, filter.AddSingleQuotes);
}
public static string BuildClause<T>(string prefix, IList<T> values, bool addSingleQuotes)
{
// use your existing implementation, since here we don't care about types anymore --
// all we do is call ToString() on them.
// in fact, we don't need this method to be generic at all!
}
}
Of course this also gets you to the problem of whether ColFilter should know about quotes or not, but that's a design issue and deserves another question :)
I also stand by the other posters in saying that if you're trying to build something that creates SQL statements by joining strings together, you should probably stop doing it and move over to parameterized queries which are easier and, more importantly, safer.
What does the function BuildClause() look like.
It seems to me that you can create BuildClause() as an extension method on IList, and you can append the values together. I assume that you just want to call .ToString() method on different types.
If you use generics properly in C# 3.0, you can achieve what you need through implicit typing (int C# 2.0 you might need to specify the type). If your BuildClause method is made generic, it should automatically take on whatever type is passed in to its generic parameter(s):
public IList<T> BuildClause<T>(IList<T> value, object prefix)
{
Type type = typeof(T);
if (type == typeof(string))
{
// handle string
}
else if (type == typeof(int))
{
// handle int
}
// ...
}
public class ColumnFilter<T>:
where T: struct
{
public IList<T> Value { get; set; }
}
var colFilter = new ColumnFilter<string>
{
Value = new { "string 1", "string 2", "string 3" }
}
IList<string> values = BuildClause(colFilter.Value, prefix);
With generics, you can drop the ColumnType property of your ColumnFilter. Since it is generic, along with your BuildClause method, you are easily able to determine the type by doing typeof(T).
I am having trouble casting an object to a generic
Casting is a run-time operation.
Generic is compile-time information.
Don't cross the streams.
Also - if you used a decent sql parameterization generator - it will add the single quotes for you.
I don't understand the question. It works for me. It could be as simple as droping the cast? What am I missing?
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1 {
class Foo<T> : List<T> {
}
class Program {
static void Main(string[] args) {
var a = new Foo<int>();
a.Add(1);
var b = new Foo<string>();
b.Add("foo");
Console.WriteLine(BuildClause(a, "foo", true));
Console.WriteLine(BuildClause(b, "foo", true));
}
private static string BuildClause<T>(IList<T> inClause, string strPrefix, bool addSingleQuotes) {
StringBuilder sb = new StringBuilder();
//Check to make sure inclause has objects
if (inClause.Count == 0)
throw new Exception("Item count for In() Clause must be greater than 0.");
sb.Append(strPrefix).Append(" IN(");
foreach (var Clause in inClause) {
if (addSingleQuotes)
sb.AppendFormat("'{0}'", Clause.ToString().Replace("'", "''"));
else
sb.Append(Clause.ToString());
sb.Append(',');
}
sb.Length--;
sb.Append(") ");
return sb.ToString();
}
}
}
The type for the IList must be known at compile time. Depending on what you want to do, you might be able to cast the list to an IList or IEnumerable (without generics) and then iterate over the objects

Categories

Resources