best way to check class - c#

I have a method which is taking in a parameter that is a Interface object
like this
private void SomeMethod(InterfaceA IUA)
Inside the method I have a statement like this
ClassD someVar = (ClassD)(((ClassC)((ClassB)IUA)).D);
everything if fine and dandy. However, in certain cases the object IUA might be instance of ClassZ rather than ClassB. So in that case the above line errors out. Is there a way to find out, before doing above statement, that which class does the object really belong to? If i know that before hand then I can have an If statement and do the following
ClassZ someVar = (ClassD)(((ClassC)((ClassZ)IUA)).Z);
I come from java background...In java i know we have getClass() ...what would be the equivalent in .net?

You really shouldn't be writing code like this without good reason.
That said: you can use is
if (a is ClassB)
{
ClassB b = (ClassB)a;
}
else if (a is ClassZ)
{
ClassZ z = (ClassZ)a;
}
...or as:
ClassB b = a as ClassB;
if (b != null)
{
// ...
}

Well, for starters, you're not really supposed to downcast from interface to a class, unless you have a really good reason to do so. If you need ClassD functionality, then your method should receive ClassD, not InterfaceA.
Another thing that confuses me is the multiple downcasting. I use both Java and C# and I've never seen the need to do a multiple cast like that.
Finally, you could use operator "is" to find out whether certain type inherits from a certain class or implements a certain interface, as in
if (IUA is ClassD)
{
// do something
}

You can do
if (someVar is ClassZ)
Which returns TRUE if someVar is-a ClassZ,
or
someVar.GetType ()
to get the actual class

How about
if(IUA is ClassB)
someVar = (IUA as ClassB).B;
elseif (IUA is ClassZ)
someVar = (IUA as ClassZ).Z;
That should work, though you get the mandatory scolding that this is a rather poor architecture.

What is the point of passing the interface if your just going to cast it away? You might want to re-evaluate the design as code like this defeats the purpose of polymorphism.
Also you should not use 'is' to test the type. Since you are going to cast the object anyway you should use 'as' and test for null.

Okay, a few different options here:
The equivalent for Java's getClass() is GetType(); you can use typeof(...) to retrieve the Type object for a type you know at compile-time. This isn't the best way of testing things though, unless you're interested in exact equality.
The equivalent of Java's instanceof operator is the is operator in C#:
if (x is SomeType) ...
This can be used with boxed values to check for value types, too:
if (x is int) ...
A related operator is the as operator, which doesn't return true or false, but a reference of the type specified. The type has to be a nullable type (reference or nullable value type) and the result is the original value but strongly typed as the target type if the value is a reference of an appropriate type, or null otherwise. For instance:
object x = "hello";
string y = x as string; // y = "hello" now
Stream z = x as Stream; // z = null now
In the case where you want to check whether or not a reference is of a particular type, and then use it as a reference of that type, a common pattern is:
object x = GetObjectFromSomewhere();
string y = x as string;
if (y != null)
{
Console.WriteLine(y.Length); // Whatever
}
This is more efficient than the equivalent to what's required in Java:
object x = GetObjectFromSomewhere();
if (x is string)
{
string y = (string) x;
Console.WriteLine(y.Length); // Whatever
}
If it's a bug for the reference to be of the wrong type, just cast - that way you'll get an exception thrown if you've got a bug, which is almost certainly the best course of action at that point.

I don't think it's necessary to cast IUA to ClassB. You're not using any of the ClassB methods as far as I can tell.

You could do something like
If (IUA is ClassB)
//I am class b
However, given that your method is taking an interface, I would question your design if you are looking to get back to the actual concrete type. Can you re-factor to create an interface method that you can use to perform the actions of that method.

From MSDN:
public static void Test (object o)
{
Class1 a;
Class2 b;
if (o is Class1)
{
Console.WriteLine ("o is Class1");
a = (Class1)o;
// do something with a
}
else if (o is Class2)
{
Console.WriteLine ("o is Class2");
b = (Class2)o;
// do something with b
}
else
{
Console.WriteLine ("o is neither Class1 nor Class2.");
}
}

You should use method overloading, this is how it should look:
private void SomeMethod(ClassB obj) {
DoMoreStuff(obj.B);
}
private void SomeMethod(ClassZ obj) {
DoMoreStuff(obj.Z);
}
private void DoMoreStuff(int val) {
// ..
}

Related

Know if a type can be converted to string representing the data [duplicate]

I am writing an interop between a php service and our crm. One of the things I need to do is make sure that simple types get converted ToString() for use later in a json converter.
I am not sure even what the name is for 'simple types' but it can be defined like this... "an object that represents a low level variable type, containing a single value, not a class or anything with executable functions etc"
I've found that int, string, bool, double, and surprisingly enum will ToString() with pretty predictable results.
int x = 0;
bool y = true;
double z = 1.59 // money
CustomEnum theEnum = CustomEnum.somevalue;
x.ToString() results in "0"
y.ToString() results in "true"
z.ToString() results in "1.59"
theEnum.ToString() results in "somevalue"
But if I use this:
List<int> iList = new List<int>();
iList.Add(1);
MyClass theClass = new MyClass();
iList.ToString() results in "System.Collections.Generic.List`1[System.Int32]"
theClass.ToString() results in "STTI.NKI.Interop.MyClass"
I'm not limited to lists. I could have an ExpandoObject, or a class etc.
I understand EXACTLY why this happens, and I want to know if there is a quick way to determine if an object of unknown type will ToString() into an expected value, and not the type name. I find it an antipattern to do something like
switch (theObject.GetType())
case typeof(int):
case typeof(bool):
case typeof(doulble):
etc
I am not sure what the terms are, so googling my answer is proving difficult.
So you want to check whether a type has a overridden ToString method? Why not just check whether the value returned by ToString is equal to the value returned by the default implementation of ToString?
From here, we know the default implementation of ToString is
return GetType().ToString();
So, we can use this to check whether an object has overridden the ToString method:
bool toStringOverridden = someObject.GetType().ToString() !=
someObject.ToString();
The ToString method is a virtual one and the default implementation is defined in the Object class and simply returns the name of the type of the object:
public virtual string ToString()
{
return this.GetType().ToString();
}
int for example, overrides this method to return a meaningful representation.
What you can do is use reflection to detect whether a type overrides the ToString method like this:
public static bool OverridesToString(Type type)
{
return type.GetMethod("ToString", new Type[0]).DeclaringType != typeof(object);
}
If it does, there is a very good chance that the ToString method would return something meaningful.
Option 1: make sure that every Object will overwrite ToString().
Option 2: Use reflection to get all object properties and concat them.
Maybe you can do something similar to this:
bool ToStringIsTyped<T>(T myObj)
{
return myObj.ToString().Contains(typeof(T).FullName);
}
It may not work in all cases, but possibly could be expanded
I Think this is what you are looking, in the GetMethod the second argument is an empty array to watch for the .ToString(), just convert the i.GetType().GetMethod("ToString", new Type[] { }).DeclaringType == typeof(object) to a function and there you go.
class Program
{
static void Main(string[] args)
{
int i = 55;
var s = "some string";
var x = new List<string>();
Console.WriteLine(i.ToString());
Console.WriteLine(i.GetType().GetMethod("ToString", new Type[] { }).DeclaringType == typeof(object));
Console.WriteLine(s.ToString());
Console.WriteLine(s.GetType().GetMethod("ToString",new Type[]{}).DeclaringType == typeof(object));
Console.WriteLine(x.ToString());
Console.WriteLine(x.GetType().GetMethod("ToString",new Type[]{}).DeclaringType == typeof(object));
}
}
...way to determine if an object of unknown type will ToString() into an expected value, and not the type name...
The default implementation of ToString() on object, according to documentation, returns "the fully qualified name of the object's type".
So we could come up with the hypothesis that whenever ToString() is overridden, its output will be "useful" in the sense you specified in the question.
To detect whether a function called is an override, we can make use of this answer, like so:
if(typeof(ObjectX).GetMethod("ToString").DeclaringType == typeof(ObjectX))
{
/* ObjectX has overridden ToString() */
}
else
{
/* ObjectX has inherited ToString() from its base class(es) */
}
Using reflection can add too much overhead, so I reckon it's better to create a generic method and add a constraint like: where T : IFormattable

IS vs. AS vs. IsAssignableFrom - What are the differences when checking for objectTypes and Interfaces?

I'm sort of new to C# and i was wondering if you could help me out.
The scenario:
public bool ObjectImplementsSpecificInterface (object obj)
{
// 1.
if (obj is IExampleInterface)
{
return true;
}
// 2.
var tmp = obj as IExampleInterface;
if (tmp != null)
{
return true;
}
// 3.
if (typeof(IExampleInterface).IsAssignableFrom (obj.GetType ()))
{
return true;
}
}
The Goal: Determine wether the object o implements the given Interface-Definition IExampleInterface or not.
The questions:
Which implementation is best practice?
Disregarding the first question, which one is technically the most correct?
What are the specific differences in the operators? MSDNAA isn't truly detailed on them.
Which call takes the longest / shortest?
"Is" operator allows you to check if particular instance is of particular type or inherits this type wheras IsAssignableFrom allows you to check if a Type is castable to another Type.
So if you have a situation where you must evaluate if some object is of particular type then you use is:
Random r = new Random();
if (r is Random)
{
reutrn true;
}
But if you have only type like such method:
public bool CheckIfTypeIsRandom(Type typeKnownAtRuntime)
{
if (typeof(Random).IsAssignableFrom(typeKnownAtRuntime)
{
return true;
}
return false;
}
Then you must use IsAssignableFrom.
All three ways will provide the same result, and take roughly the same time, but only the first one is designed specifically for your situation.
When you start with an object, and all you need is to know whether or not its class implements a given interface, the first approach (i.e. the is operator) is the most appropriate.
The second approach is there for cases when you need to find out if an object is an implementation of an interface, and also use that object after casting it to the interface. If you plan to throw away the result of the cast after null-checking it, there is no point in performing the cast in the first place.
The third approach is mostly for use with reflection, when you have a System.Type object instead of the object itself.
The gathered information and propably correct answer from the posts below is the following:
Operator is:
Should be used to determine wether the object implements an interface or is of a specific type, so this is the answer to my question: Which one is best practice?
Operator as:
should take longer than is.
is generally used to store the object into a var that will represent the correct type.
used to process the object further aka. call a function or check the type of the interface.
Operator isAssignableFrom:
Checks wether the object can be casted to another type.
Should be used if the type of the object is unknown during runtime.
var impInterface = obj is ISampleInterface;
What do you mean by "technically" ? They all work. if all you want ois to know whether it implments the interface, that's what is is for. If you want a new variable which is cast as the interface, then use as.
is determines if object derives from a type and returns a Boolean. as attempts to cast the object as the type, and return the new variable cast to the type, or null if it cannot. (but you know this from your question).
as should probably take longer, even if the cast works.
1) If you just want to check, if an object is of a type or implements an interface, use is.
2) If you want to check the type or interface and do some stuff with the object, use as. So instead of:
if (obj is A) {
A casted = (A) obj;
casted.MethodOfA ();
}
You should do
A casted = obj as A
if (casted != null) {
casted.MethodOfA ();
}
3) Use this method only when 1) is not available, e.g. you have the type as an object of type Type instead of of T.

C# reflection and instantiation - is there a way to do Activator.CreateInstance(myType){ X = x }?

I'm not sure of the terminology for this kind of code, but I want to know if it's possible to instantiate variables after the parentheses, but whilst using reflection.
I have a map which gets loaded from an XML file. This is a collection of (int X, int Y, string S) where the X,Y is the position of some terrain, and S is a string representing the type of the terrain. I have a dictionary to pass between the strings and the relevant types; for example one key-value pair might be "Tree", typeof(Tree).
When using reflection, although I know it's possible to instantiate with parameters, the only way I'm comfortable is just by using Activator.CreateInstance(Type t), i.e. with an empty constructor.
When I had the maps hard coded, I would originally instantiate like this (within some i,j for loop):
case: "Tree"
world.Add( new Tree(i,j) );
Whilst starting to think about reflection and my save file, I changed this to:
world.Add( new Tree() { X = i, Y = j }
However, I realised that this won't work with reflection, so I am having to do the following (Tree inherits from Terrain, and the dictionary just converts the XML save data string to a type):
Type type = dictionary[dataItem.typeAsString];
Terrain t = (Terrain)Activator.CreateInstance(type);
t.X = i;
t.Y = j;
world.Add(t);
I would prefer to do this using something like
Type type = dictionary[dataItem.typeAsString];
world.Add((Terrain)Activator.CreateInstance(type) { X = i, Y = j }
Is there any shortcut like this? I guess if not I could edit world.Add to take an X and Y and cast to Terrain in there to access those variables, but I am still curious as to a) what this {var1 = X, var2 = Y} programming is called, and b) whether something similar exists when using reflection.
This syntax is called Object Initializer syntax and is just syntactic sugar for setting the properties.
The code var result = new MyType { X = x } will be compiled to this:
MyType __tmp = new MyType();
__tmp.X = x;
MyType result = __tmp;
You will have to do that yourself using PropertyInfo.SetValue if you know the instantiated type only at runtime or use the normal property setters if the type is known at compile time.
The answer is no, because the object initialization syntax you mention (introduced with LINQ in 3.0) is an illusion of the compiler. As in, when you type this
var foo = new Foo { Bar = "baz" };
the compiler actually converts it into CLS-compliant IL which equates to
var foo = new Foo();
foo.Bar = "baz";
Phil Haack has a great blog post which not only covers the details of this rewriting done by the compiler, but also some side effects it can cause when dealing with types that implement IDisposable
As all of this is nothing but a feint by the compiler, there is no equivalent using reflection (i.e., Activator.CreateInstance(Type t)). Others will give you workarounds, but in the end there really is no direct equivalent.
Probably the closest generic hack you could manage would be to create a method that accepted an object, then used reflection in order to identify the properties of that object and their respective values in order to perform object initialization for you. It might be used something like this
var foo = Supercollider.Initialize<Foo>(new { Bar = "baz" });
and the code would be something like (this is off the top of my head)
public sealed class Supercollider
{
public static T Initialize<T>(object propertySource)
{
// you can provide overloads for types that don't have a default ctor
var result = Activator.CreateInstance(typeof(T));
foreach(var prop in ReflectionHelper.GetProperties(typeof(T)))
ReflectionHelper.SetPropertyValue(
result, // the target
prop, // the PropertyInfo
propertySource); // where we get the value
}
}
You'd have to get each property from the anonymous object, find a property in your target type with the same exact name and type, then get the value from that property in the anonymous object and set the value of your target's property to this value. Its not incredibly hard, but its absolutely prone to runtime exceptions and issues where the compiler chooses a different type for the anonymous type's property, requiring you be more specific (e.g., new { Bar = (string)null }), which screws with the elegance of the thing.
(T)Activator.CreateInstance(typeof(T), param1, param2, ...);
As described HERE.
public sealed class ReflectionUtils
{
public static T ObjectInitializer<T>(Action<T> initialize)
{
var result = Activator.CreateInstance<T>();
initialize(result);
return result;
}
}
public class MyModel
{
public string Name{get;set;}
}
And after that just make the call :
var myModel = ReflectionUtils.ObjectInitializer<MyModel>(m =>
{
m.Name = "Asdf"
});
The advantage is that in this way you will have type safety and use reflection as minimum required, because we all know that reflection is an expensive operation that should be avoided as much as possible.
You could create a constructor which takes those arguments, then use
Activator.CreateInstance(type, i, j)
But you won't be able to use the object initialization syntax. Which is just sugar candy for setting the properties.

What's the point of "As" keyword in C#

From the docs:
The as operator is like a cast except that it yields null on conversion failure instead of raising an exception. More formally, an expression of the form:
expression as type
is equivalent to:
expression is type ? (type)expression : (type) null
except that expression is evaluated only once.
So why wouldn't you choose to either do it one way or the other. Why have two systems of casting?
They aren't two system of casting. The two have similar actions but very different meanings. An "as" means "I think this object might actually be of this other type; give me null if it isn't." A cast means one of two things:
I know for sure that this object actually is of this other type. Make it so, and if I'm wrong, crash the program.
I know for sure that this object is not of this other type, but that there is a well-known way of converting the value of the current type to the desired type. (For example, casting int to short.) Make it so, and if the conversion doesn't actually work, crash the program.
See my article on the subject for more details.
https://ericlippert.com/2009/10/08/whats-the-difference-between-as-and-cast-operators/
Efficiency and Performance
Part of performing a cast is some integrated type-checking; so prefixing the actual cast with an explicit type-check is redundant (the type-check occurs twice). Using the as keyword ensures only one type-check will be performed. You might think "but it has to do a null check instead of a second type-check", but null-checking is very efficient and performant compared to type-checking.
if (x is SomeType )
{
SomeType y = (SomeType )x;
// Do something
}
makes 2x checks, whereas
SomeType y = x as SomeType;
if (y != null)
{
// Do something
}
makes 1x -- the null check is very cheap compared to a type-check.
Because sometimes you want things to fail if you can't cast like you expect, and other times you don't care and just want to discard a given object if it can't cast.
It's basically a faster version of a regular cast wrapped in a try block; but As is far more readable and also saves typing.
It allows fast checks without try/cast overhead, which may be needed in some cases to handle message based inheritance trees.
I use it quite a lot (get in a message, react to specific subtypes). Try/cast wouuld be significantly slower (many try/catch frames on every message going through) - and we talk of handling 200.000 messages per second here.
Let me give you real world scenarios of where you would use both.
public class Foo
{
private int m_Member;
public override bool Equals(object obj)
{
// We use 'as' because we are not certain of the type.
var that = obj as Foo;
if (that != null)
{
return this.m_Member == that.m_Member;
}
return false;
}
}
And...
public class Program
{
public static void Main()
{
var form = new Form();
form.Load += Form_Load;
Application.Run(form);
}
private static void Form_Load(object sender, EventArgs args)
{
// We use an explicit cast here because we are certain of the type
// and we want an exception to be thrown if someone attempts to use
// this method in context where sender is not a Form.
var form = (Form)sender;
}
}
I generally choose one or the other based on the semantics of the code.
For example, if you have an object that you know that it must be an string then use (string) because this expresses that the person writing the code is sure that the object is a string and if it's not than we already have bigger problems than the runtime cast exception that will be thrown.
Use as if you are not sure that the object is of a specific type but want to have logic for when it is. You could use the is operator followed by a cast, but the as operator is more efficient.
Maybe examples will help:
// Regular casting
Class1 x = new Class1();
Class2 y = (Class2)x; // Throws exception if x doesn't implement or derive from Class2
// Casting with as
Class2 y = x as Class2; // Sets y to null if it can't be casted. Does not work with int to short, for example.
if (y != null)
{
// We can use y
}
// Casting but checking before.
// Only works when boxing/unboxing or casting to base classes/interfaces
if (x is Class2)
{
y = (Class2)x; // Won't fail since we already checked it
// Use y
}
// Casting with try/catch
// Works with int to short, for example. Same as "as"
try
{
y = (Class2)x;
// Use y
}
catch (InvalidCastException ex)
{
// Failed cast
}

How to treat an instance variable as an instance of another type in C#

I have a simple inheritance heirarchy with MyType2 inheriting from MyType1.
I have an instance of MyType1, arg, passed in as an argument to a method. If arg is an instance of MyType2, then I'd like to perform some logic, transforming the instance. My code looks something like the code below.
Having to create a new local variable b feels inelegant - is there a way of achieving the same behavior without the additional local variable?
public MyType1 MyMethod(MyType1 arg)
{
if(arg is MyType2)
{
MyType2 b = arg as MyType2;
//use b (which modifies "arg" as "b" is a reference to it)...
}
return arg;
}
Note that the "is" and "as" is duplicating the test; either use is and then (once you know) just cast - or use as in the first place and test for null.
Re your issue; if you only want to do one thing - then cast:
if(arg is MyType2)
{
((MyType2)arg).SomeSpecialMethod();
}
Otherwise - perhaps a virtual method (on the base-type), or just refactor the logic out into another method, so you have:
if(arg is MyType2)
{
StuffThatTakesType2((MyType2)arg);
}
But persoanlly, I'd just use the extra variable:
MyType2 whatever = arg as MyType2;
if(whatever != null) {
whatever.Foo = 123;
whatever.Bar();
}
No; you need to create a separate variable.
Also, your code performs more casts than necessary; it would be a little bit faster like this:
MyType2 b = arg as MyType2;
if(b != null)
{
//Use b
}
I would say option 1 is to put all the modifying code (your comment line) as a function of MyType2, and then do (arg as MyType2).Foo() on it.
Option 2 is to implement MyMethod on both MyType1 and as an override in MyType2, and just call it without worrying. The MyType1 implementation may do nothing, which isn't the best design.
edit: technically not a violation of LSP since that only applies in the reverse of this situation (MyType2 shouldn't break behavior of MyType1).

Categories

Resources