Say I have a list of objects called components:
List<object> components = new List<object>();
Say it's populated with objects of the classes engine, wheel, frame. Now, I want to make a function that takes a class as a parameter and returns true if the list has an object of that class. Like this:
public static bool HasComponent( *the class* ) {
foreach(object c in components) {
if(c is *the class*)
return true;
}
return false;
}
How do i go about doing that? is it possible?
use linq:
components.OfType<YouType>().Any();
Use generics:
public static bool HasComponent<T>() {
foreach(object c in components) {
if(c is T)
return true;
}
return false;
}
Call it:
Obj.HasComponent<Wheel>();
You can call GetType() to get the type of any object in .Net or use the is keyword. Indeed, you could do this on the list using LINQ with something like:
components.Any(x => x is Wheel);
and substitute Wheel for the desired type.
Something more like this
public static bool HasComponent<TheType>()
{
foreach(object c in components)
{
if(c is TheType)
{
return true;
}
}
return false;
}
Or shorter
public static bool HasComponent<TheType>()
{
return components.OfType<TheType>().Count() > 0;
}
Call it with
HasComponent<TheType>()
I know some answers suggested using the "is" keyword, but you'll want to be careful in inheritance situations. e.g. If Cow derives from Animal, then HasComponent<Cow>() will return true for both. You should really compare types to avoid the problem:
public static bool HasComponent<T>()
{
return components.Any(i => i.GetType() == typeof(T));
}
Of course, you can do it without generics by passing in a type, but generics is really the way to go:
public static bool HasComponent(Type type)
{
return components.Any(i => i.GetType() == type);
}
If you are working with a multiple-threaded application, you should be sure that the object is in the list at the time you search for it. Because the other thread can remove this object at the same time as the search. So, a NullReferenceException could be thrown. In order to avoid this situation, you can use this function.
public static bool HasComponent<T>()
{
foreach (object c in components)
{
lock (c.GetType())
{
if (c is T)
{
return true;
}
}
}
return false;
}
But, to call this function your list should be static.
To find this out, we should use an extended for loop that is 'foreach', which traverses through all types of class objects and checks the desired object of specific class and returns either true or false.
public static bool HasComponent<Type>() {
foreach(object c in l) {
if(object c in Type)
return true;
}
return false;
}
Related
I want to know how to compare an object, that if a list contains that object by ignoring case
Suppose take an example for this
Class A
{
public string p1;
public string p2;
}
Class B
{
List<A> lst=new List<A>();
A obj=new a();
A obj1=new a();
obj1.p1="ABCD";
obj1.p2="xyz";
obj.p1="abcd";
obj.p2="XYZ";
lst.add(obj1);
lst.contains(obj)//return false
}
So I want to know how to compare it?
You can implement IEquatable to control how your objects are compared. You can then specify exactly how you want the comparison to work by implementing the Equals() method:
public bool Equals(A other)
{
return this.P1.ToLower().Equals(other.P1.ToLower());
}
Your
lst.Contains(obj)
Should then work as you need.
In class A override the Equals method to compare each of the properties ignoring case.
Then use:
bool found = lst.FirstOrDefault(x => x.Equals(obj)) != null;
var result = lst.FirstOrDefault(c => c.p1 == obj.p1 && c.p2 == obj.p2);
if(result != null)
{
//Your Code is here.
}
The problem is this:
I want a generic function that has an out-parameter of the generic type.
Restrict the generic type to ref-type and there is no problem ofcourse.
But I wanted a totally unrestricted generic type! No new() or class/struct-restrictions!
public class A
{ }
public class B<T> : A
{
public T t;
public B(T i)
{
this.t = t;
}
}
public static class S
{
public static bool Test<T>(ref A a, out T t)
{
C<T> c = a as C<T>;
if(c != null)
{
t = c.t;
return true;
}
else
return false;
}
}
class Run
{
static void Main(string[] args)
{
C<SomeType> c = new C<SomeType>(new SomeType(...));
SomeType thing;
S.Test<SomeType>(c,thing);
}
}
The above code illustrates what I want to do. I want to set the out parameter, but only under a similar condition as the one depicted. In the false-case of Test(...) I'm totally uninterested in the value of out t. But the above is ofcourse not working code.
The problem above is that an out parameter must be initialized. But maybe initialization is sometimes expensive (depends on type of T) and I don't want to initialize a dummy class instance just to make the compiler stop complaining. So the question then becomes: How do you initialize an unknown type (and making sure it is initialized to null if it's a class)??
Well in theory you should be able to write something like
public static bool Test<T>(ref A a, out T t)
{
//...
else
{
if(typeof(T).IsValueType)
{
t = (T)0; //Can't cast from int to T error (Yeah, this is a little tricky...)
//OR:
t = new T(); //No-no, doesn't have the new()-restriction on T (But we know it's a value type... life sucks)
}
else
t = null; //Error: Can't set to null! T could be valueType! (No it CAN'T... again life sucks)
return false;
}
}
But alas it's not so simple. The first problem is when T is value-type, we should be able to create it but compiler wont let us. The second problem is similar: "It could be a value-type!" - no, I just made sure it wasn't. It should work but it doesn't. Very annoying.
Ok. So we start to go creative... after all, there is this nice class called Object, and it has a special relation to all things C#'ish.
public static bool Test<T>(ref A a, out T t)
{
//...
else
{
if(typeof(T).IsValueType)
{
t = (T)(object)0; //Works ONLY if T is valuetype: int, otherwise you get a "must be less than infinity"-error.
}
else
{
t = (T)(object)null; //Null ref exception in the cast...
}
return false;
}
}
This compiles atleast. But it's still rubbish. Runtime-error galore.
The problem with the value-type is that the object-type remembers what type it really is and when trying to cast to something else... strange things happen (infinity? Really??)
Well this damn well should be doable! So lets be more creative!
public static bool Test<T>(ref A a, out T t)
{
//...
else
{
if(typeof(T).IsValueType)
{
//... still rubbish here
}
else
{
object o = null;
t = (T)o; //Tricked you stupid compiler!
}
return false;
}
}
That's right! It looks a stupid insignificant change... But this compiles - and for non-value-types this runs and gives exactly the result we want! If T is a ref-type it gets initilized to null.
Still the problem with value-types. Somewhat reluctantly creativity turns it attention to Reflection. After some random digging around on reflection-stuff, looking for something worth trying out (and no! you cant get the constructor for a value-type, it returns null) I stumbled across a small note on msdn:
"To create an instance of a value type that has no instance
constructors, use the CreateInstance method."
Enter CreateInstance<T>() - http://msdn.microsoft.com/en-us/library/0hcyx2kd.aspx.
"The CreateInstance generic method is used by compilers to implement
the instantiation of types specified by type parameters."
Now we're getting somewhere! Sure it does say
"In general, there is no use for the CreateInstance in application
code, because the type must be known at compile time. If the type is
known at compile time, normal instantiation syntax can be used (new
operator in C#, New in Visual Basic, gcnew in C++)."
But hey - we are not quite doing general stuff, we are in creative-mode, and the compiler is grumpy towards us. Totally justifies giving it a try.
public static bool Test<T>(ref A a, out T t)
{
//...
else
{
if(typeof(T).IsValueType)
{
t = Activator.CreateInstance<T>(); //Probably not your everyday code...
}
else
{
object o = null;
t = (T)o;
}
return false;
}
}
AND BAM! That was it! It totally works soo good!
Below is some code thats been tested and run in both VS2010SP1 and MonoDevelop (with Unity3.4)
using System;
namespace GenericUnrestrictedOutParam
{
class Program
{
class TestClass
{
public int i;
}
struct TestStruct
{
int i;
TestClass thing;
};
public static void NullWorkaround<T>(out T anything)
{
if (typeof(T).IsValueType)
{
anything = Activator.CreateInstance<T>();
}
else
{
object o = null;
anything = (T)o;
}
}
static void Main(string[] args)
{
int i;
float f;
string s;
TestStruct ts;
TestClass c;
NullWorkaround<int>(out i);
NullWorkaround<float>(out f);
NullWorkaround<string>(out s);
NullWorkaround<TestStruct>(out ts);
NullWorkaround<TestClass>(out c);
} //Breakpoint here for value-checking
}
}
And the glorious "output" (from locals-panel # breakpoint):
args {string[0]} string[]
i 0 int
f 0.0 float
s null string
- ts {GenericUnrestrictedOutParam.Program.TestStruct} GenericUnrestrictedOutParam.Program.TestStruct
i 0 int
thing null GenericUnrestrictedOutParam.Program.TestClass
c null GenericUnrestrictedOutParam.Program.TestClass
Even the struct with a value and a class-type in it is beautifully handled: value type is 0, class instance is null.
Mission accomplished!
Your workaround seems unnecessary - you just need default(T) which works for both reference and value types:
public static bool Test<T>(ref A a, out T t)
{
t = default(T);
return true;
}
This is a pretty general question, but the specific thing I'm doing is simple so I'm including the code. How do I check for type compatibility between two objects when I don't know the type of either at compile time?
That is, I can do if (object is SomeType) when SomeType is a type name known at compile time. GetType() is not sufficient because it will not work with derived types. Basically I want to be able to say, if (object.IsTypeOfOrIsDerivedFrom(someType)) where sig of this magical method is IsTypeOfOrIsDerivedFrom(Type type)
Here is the context.
// Return all controls that are (or are derived from) any of a list of Types
public static IEnumerable<Control> FindControls(this Control control, IEnumerable<Type> types, bool recurse)
{
foreach (Control ctl in control.Controls)
{
/// How can I compare the base types of item & ctl?
if (types.Any(item=> .... ))
{
yield return (ctl);
}
if (recurse && ctl.Controls.Count > 0)
{
IEnumerable<Control> subCtl = ctl.FindControls(types,true);
if (subCtl != null)
{
yield return (subCtl);
}
}
}
yield break;
}
You can use, Type.IsAssignableFrom e.g.
public class Foo { }
public class Bar : Foo { }
...
bool compatible = typeof(Foo).IsAssignableFrom(typeof(Bar));
This question already has answers here:
C# implementation of deep/recursive object comparison in .net 3.5
(6 answers)
Closed 8 years ago.
I have two complex objects of the same type. I want to compare both the objects to determine if they have the exact same values. What is the efficient way of doing this ?
sample class structure given below:
class Package
{
public List<GroupList> groupList;
}
class GroupList
{
public List<Feature> featurelist;
}
class Feature
{
public int qty;
}
Okay, so you want deep unordered structural comparison. The "unordered" part is tricky, and in fact it is a strong hint that your classes are not designed right: List<T> is inherently ordered, so perhaps you would rather want to use a HashSet<T> there (if you don't expect to have any duplicates). Doing so would make the comparison both easier to implement, and faster (though insertions would be slower):
class Package
{
public HashSet<GroupList> groupList;
public override bool Equals(object o)
{
Package p = o as Package;
if (p == null) return false;
return groupList.SetEquals(p.groupList);
}
public override int GetHashCode()
{
return groupList.Aggregate(0, (hash, g) => hash ^ g.GetHashCode());
}
}
class GroupList
{
public HashSet<Feature> featureList;
public override bool Equals(object o)
{
GroupList g = o as GroupList;
if (g == null) return false;
return featureList.SetEquals(g.featureList);
}
public override int GetHashCode()
{
return featureList.Aggregate(0, (hash, f) => hash ^ f.GetHashCode());
}
}
class Feature
{
public int qty;
public override bool Equals(object o)
{
Feature f = o as Feature;
if (f == null) return false;
return qty == f.qty;
}
public override int GetHashCode()
{
return qty.GetHashCode();
}
}
If you want to keep using List<T>, you'll need to use LINQ set operations - note, however, that those are significantly slower:
class Package
{
public List<GroupList> groupList;
public override bool Equals(object o)
{
Package p = o as Package;
if (p == null) return false;
return !groupList.Except(p.groupList).Any();
}
}
class GroupList
{
public List<Feature> featureList;
public override bool Equals(object o)
{
GroupList g = o as GroupList;
if (g == null) return false;
return !featureList.Except(f.featureList).Any();
}
}
For complex objects, I would consider operator overloading.
On the overloaded operator, I would define my condition for equality.
http://msdn.microsoft.com/en-us/library/aa288467%28VS.71%29.aspx
We always just end up writing a method on the class that goes through everything and compares it. You could implement this as IComparable, or override Equals.
As the comment said, depends on how "exact" you want to measure.
You could just override equality and implement a GetHashCode method, however this does not guarantee they are exact matches. Will however ensure they are "very likely" an exact match.
Next thing you could do, is to go through every property/field in the class and compare those hash values. This would be "extremely likely" an exact match.
And to truly get an exact match, you have to compare every field and member in a recursive loop...not recommended.
If I were you, I would implement the IComparable Interface on the two types:
http://msdn.microsoft.com/en-us/library/system.icomparable.aspx
From there you can use .CompareTo, and implement the exact comparisons required under your circumstances. This is a general best practice within .NET and I think applies well to your case.
Depends on what you what you want to do with comparison. Like others have pointed out IComparer is a good choice. If you are planning on using lambdas and LINQ, I would go with IEqualityComparer
http://msdn.microsoft.com/en-us/library/system.collections.iequalitycomparer.aspx
In general, you need a method to check the two, regardless of whether or not you overload equals, or use IComparer.
You asked how to do it most efficiently, here are some tips:
Your equality method should try to give up quickly, e.g. check if the size of the lists are the same, if they are not then return false right away
If you could implement an efficient hashCode, you could compare the hashes first, if they are not equal then the objects are not equal, if they are equal, then you need to compare the objects to see if the objects are equal
So in general, do the fastest comparisons first to try to return false.
Here is a somewhat simplified way to do it, using reflection. You will probably need to add other checks of datatypes for specific comparisons or loop through lists etc, but this should get you started.
void Mymethod(){
Class1 class1 = new Class1();
//define properties for class1
Class1 class2 = new Class1();
//define properties for class2
PropertyInfo[] properties = class1.GetType().GetProperties();
bool bClassesEqual = true;
foreach (PropertyInfo property in properties)
{
Console.WriteLine(property.Name.ToString());
if (property.GetValue(class1, null) != property.GetValue(class2, null))
{
bClassesEqual = false;
break;
}
}
}
I am trying to derive the type of an object at runtime. Specifically I need to know two things whether it implements ICollection or IDto. Currently my only solution I have been able to find is this:
private static bool IsACollection(PropertyDescriptor descriptor)
{
bool isCollection = false;
foreach (Type type in descriptor.PropertyType.GetInterfaces())
{
if (type.IsGenericType)
{
if (type.GetGenericTypeDefinition() == typeof(ICollection<>))
{
isCollection = true;
break;
}
}
else
{
if (type == typeof(ICollection))
{
isCollection = true;
break;
}
}
}
return isCollection;
}
private static bool IsADto(PropertyDescriptor descriptor)
{
bool isDto = false;
foreach (Type type in descriptor.PropertyType.GetInterfaces())
{
if (type == typeof(IDto))
{
isDto = true;
break;
}
}
return isDto;
}
However I am convinced there has to be a better way than this. I have tried comparing in a normal fashion such as:
if(descriptor.PropertyType == typeof(ICollection<>))
However, this fails when using reflection yet when not using reflection it works fine.
I don't want to iterate through the interfaces for every field of my entity. Could someone shed some light on another method in which to do this? Yes, I am prematurely optimizing, but it looks ugly too so please humor me.
Caveats:
It could or could not be generic, such as IList<> or just ArrayList thus why I am looking for ICollection or ICollection<>. So I assume I should use IsGenericType in an if statement to know whether to test using ICollection<> or not.
Thanks in advance!
This:
type == typeof(ICollection)
will check if the type of property is exactly ICollection. That is, it will return true for:
public ICollection<int> x { get; set; }
but not for:
public List<int> x { get; set; }
If you want to check if the type of property is, or is derived from, ICollection, the simplest way is to use Type.IsAssignableFrom:
typeof(ICollection).IsAssignableFrom(type)
and the same goes for generic:
typeof(ICollection<>).IsAssignableFrom(type.GetGenericTypeDefinition())
Does type.IsAssignable help in this case?
EDIT: Sorry, it should have been Type.IsAssignableFrom