Why I am getting the Unable to cast exception here - c#

Here is the code:
interface IA
{
}
interface IC<T>
{
}
class A : IA
{
}
class CA : IC<A>
{
}
class Program
{
static void Main(string[] args)
{
IA a;
a = (IA)new A(); // <~~~ No exception here
IC<IA> ica;
ica = (IC<IA>)(new CA()); // <~~~ Runtime exception: Unable to cast object of type 'MyApp.CA' to type 'MyApp.IC`1[MyApp.IA]'.
}
}
Why am I getting the casting exception in the last line of the code ?

You need to declare IC as interface IC<out T> for the cast to work. This tells the compiler that IC<A> can be assigned to a variable of type IC<IA>.
See, this page for an explanation.

you can do
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
interface IPerson
{
}
//Have to declare T as out
interface ICrazy<out T>
{
}
class GTFan : IPerson
{
}
class CrazyOldDude : ICrazy<GTFan>
{
}
class Program
{
static void Main(string[] args) {
IPerson someone;
someone = (IPerson)new GTFan(); // <~~~ No exception here
ICrazy<GTFan> crazyGTFanatic;
ICrazy<IPerson> crazyPerson;
crazyGTFanatic = new CrazyOldDude() as ICrazy<GTFan>;
crazyGTFanatic = (ICrazy<GTFan>)(new CrazyOldDude());
crazyPerson = (ICrazy<IPerson>)crazyGTFanatic;
}
}
}

Related

C# - Casting problems

When trying to cast a class which defines a custom generic to the subclass I get an error. What did I wrong?
using System.Collections.Generic;
interface IStorageComponent { }
abstract class CollectionManager<T> where T : IStorageComponent { }
class Bar : IStorageComponent { }
class Foo : CollectionManager<Bar> { }
class Storage
{
static int Main(string[] args)
{
List<CollectionManager<IStorageComponent>> manager = new List<CollectionManager<IStorageComponent>>
{
new Foo() // <-- cannot convert from 'Foo' to 'CollectionManager<IStorageComponent>'
};
return 0;
}
}

Inconsistent accessibility with protected internal member

Attempting to make a protected internal member of a protected internal class within a public class results with the following issue:
Inconsistent accessibility: field type
'what.Class1.ProtectedInternalClass' is less accessible than field
'what.Class1.SomeDataProvider.data'
The accessibility should be equivalent, as far as I know.
Where am I mistaken?
Origination class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace what
{
public class Class1
{
// This class cannot be modified, is only
// here to produce a complete example.
public class PublicClass
{
public PublicClass() { }
}
protected internal class ProtectedInternalClass : PublicClass
{
public ProtectedInternalClass() { }
public void SomeExtraFunction() { }
}
public class SomeDataProvider
{
public int AnInterestingValue;
public int AnotherInterestingValue;
protected internal ProtectedInternalClass data; //<--- Occurs here.
public PublicClass Data { get { return data; } }
}
public static SomeDataProvider RetrieveProvider()
{
SomeDataProvider provider = new SomeDataProvider();
provider.data = new ProtectedInternalClass();
provider.data.SomeExtraFunction();
return provider;
}
}
}
Verifying protected and internal properties, same assembly:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace what
{
public class Class2 : Class1
{
public Class2()
{
var pi = new ProtectedInternalClass();
var provider = new SomeDataProvider();
provider.data = pi;
}
// no errors here
}
public class Class3
{
public Class3()
{
var pi = new Class1.ProtectedInternalClass();
var provider = new Class1.SomeDataProvider();
provider.data = pi;
}
// no errors here
}
}
Verifying protected and internal properties, different assembly:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace some_other_assembly
{
public class Class4 : what.Class1
{
public Class4()
{
var pi = new ProtectedInternalClass();
var provider = new SomeDataProvider();
provider.data = pi;
}
// no errors here
}
public class Class5
{
public Class5()
{
var pi = new what.Class1.ProtectedInternalClass(); // <--- Inaccessible due to protection level, as it should be.
var provider = new what.Class1.SomeDataProvider();
provider.data = pi; // <--- Intellisense implies inaccessible, but not indicated via error.
}
}
}
The protected applies to different classes, and this can be seen with
class Derived : what.Class1.SomeDataProvider // note: Derived is not a nested class
{
public void f()
{
var data = this.data;
}
}
in a different assembly.
this.data has to be accessible, since the class derives from SomeDataProvider. Its type, ProtectedInternalClass, is not accessible, since the class does not derive from Class1.

Why is System.Type.IsPublic returning as false?

I have a little console application that I'm tinkering with just to learn something new.
In the code below, in Console.WirteLine(), if I test t.IsAbstract, or t.IsSealed, my output is AbstractClass true, or SealedClass true respectively. All others return false as I expect.
However, if I test t.IsPublic, everything, including both PublicClass and PublicInterface return false. Why is that?
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
namespace ConsoleApplication1
{
class Test
{
static void Main(string[] args)
{
Assembly assembly = Assembly.GetExecutingAssembly();
Type[] assemblyTypes = assembly.GetTypes();
foreach (Type t in assemblyTypes)
Console.WriteLine(t.Name + " " + t.IsPublic);
Console.ReadKey();
}
private class PrivateClass { }
public class PublicClass { }
protected class ProtectedClass { }
sealed class SealedClass { }
abstract class AbstractClass { }
interface myInterface { }
public interface PublicInterface { }
}
}
Because they are nested inside of Test.
From the documentation: true if the Type is declared public and is not a nested type; otherwise, false.
As #Jeb's answer and the docs suggest, typeof(PublicClass) should have a value of true for the IsNestedPublic property
It's not public outside the assembly...IsNestedPublic should be true though..

C# Instantiate Class from String given an Interface

I am trying to make an instance of a class based on a string that will be retrieved from the User Interface, and then I want to access the properties of the instance of the class.
Here is an overview of what I have so far -
namespace MamdaAdapter
{
public interface IExchange
{
string GetTransport();
}
}
namespace MamdaAdapter
{
public class Exchange
{
public class Arca : IExchange
{
private const string _Transport = "tportname";
public string GetTransport()
{
return _Transport;
}
}
public static IExchange DeriveExchange(string ExchangeName)
{
IExchange SelectedExchange = (IExchange)Activator.CreateInstance(Type.GetType(ExchangeName));
return SelectedExchange;
}
}
}
namespace MyUserInterface
{
public class MainForm
{
private void simpleButton1_Click(object sender, EventArgs e)
{
IExchange SelectedExchange = Exchange.DeriveExchange("Exchange.Arca");
Console.WriteLine(SelectedExchange.GetTransport());
}
}
}
UPDATE:
Right now, I'm getting an Exception that says the "Value cannot be null" which to me means that it is unable to create the instance of the class given the string provided -
The problem here is how you specify the name of your class:
First, specify the namespace. Second, since Arca is an inner class you must use '+' instead of '.'
(...) = Exchange.DeriveExchange("MamdaAdapter.Exchange+Arca");
Assuming you UI doesnt expose the full type name, you typically want a dictionary to associate the display name to the type:
Dictionary<string, Type> _associations = new Dictionary<string, Type>();
Then, you simply instantiate the new object:
if(_associations.ContainsKey(someString))
{
Type selectedType = _associations[someString];
return Activator.CreateInstance(selectedType) as IExchange;
}
throw new ApplicationException("No type defined for that string yo");
If the string is not known at compile time, you basically need to check for the existance of the type:
var type = Type.GetType(someString);
if(type != null)
{
// Do Stuff
}
I wrote a small c# console application to simulate your need, tested ok, hope it helps:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MamdaAdapter;
using System.Reflection;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
IExchange SelectedExchange = Exchange.DeriveExchange("MamdaAdapter.Arca");
Console.WriteLine(SelectedExchange.GetTransport());
}
}
}
namespace MamdaAdapter
{
public interface IExchange
{
string GetTransport();
}
}
namespace MamdaAdapter
{
public class Arca : IExchange
{
private const string _Transport = "tportname";
public string GetTransport()
{
return _Transport;
}
}
}
namespace MamdaAdapter
{
public class Exchange
{
public static IExchange DeriveExchange(string ExchangeName)
{
IExchange SelectedExchange = (IExchange)Assembly.GetAssembly(typeof(IExchange)).CreateInstance(ExchangeName, false, BindingFlags.CreateInstance, null, null, null, null);
return SelectedExchange;
}
}
}
If the Type you are looking for is not defined in the same assembly that is executing Type.GetType you must use the AssemblyQualifiedName (something like MyNamespace.MyClass, MyAssembly, Version=1.3.0.0, Culture=neutral, PublicKeyToken=b17a5c561934e089), even the FullName is not enough. Otherwise you could first get the assembly containing the class and then execute the GetType method of the Assembly class.

Class inheriting from several Interfaces having same method signature

Say, I have three interfaces:
public interface I1
{
void XYZ();
}
public interface I2
{
void XYZ();
}
public interface I3
{
void XYZ();
}
A class inheriting from these three interfaces:
class ABC: I1,I2, I3
{
// method definitions
}
Questions:
If I implement like this:
class ABC: I1,I2, I3
{
public void XYZ()
{
MessageBox.Show("WOW");
}
}
It compiles well and runs well too!
Does it mean this single method implementation is sufficient for inheriting all the three Interfaces?
How can I implement the method of all the three interfaces and CALL THEM?
Something Like this:
ABC abc = new ABC();
abc.XYZ(); // for I1 ?
abc.XYZ(); // for I2 ?
abc.XYZ(); // for I3 ?
I know it can done using explicit implementation but I'm not able to call them. :(
If you use explicit implementation, then you have to cast the object to the interface whose method you want to call:
class ABC: I1,I2, I3
{
void I1.XYZ() { /* .... */ }
void I2.XYZ() { /* .... */ }
void I3.XYZ() { /* .... */ }
}
ABC abc = new ABC();
((I1) abc).XYZ(); // calls the I1 version
((I2) abc).XYZ(); // calls the I2 version
You can call it. You just have to use a reference with the interface type:
I1 abc = new ABC();
abc.XYZ();
If you have:
ABC abc = new ABC();
you can do:
I1 abcI1 = abc;
abcI1.XYZ();
or:
((I1)abc).XYZ();
During implementation in a class do not specify modifier o/w you will get compilation error, also specify the interface name to avoid ambiguity.You can try the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleCSharp
{
class Program
{
static void Main(string[] args)
{
MyClass mclass = new MyClass();
IA IAClass = (IA) mclass;
IB IBClass = (IB)mclass;
string test1 = IAClass.Foo();
string test33 = IBClass.Foo();
int inttest = IAClass.Foo2();
string test2 = IBClass.Foo2();
Console.ReadKey();
}
}
public class MyClass : IA, IB
{
static MyClass()
{
Console.WriteLine("Public class having static constructor instantiated.");
}
string IA.Foo()
{
Console.WriteLine("IA interface Foo method implemented.");
return "";
}
string IB.Foo()
{
Console.WriteLine("IB interface Foo method having different implementation. ");
return "";
}
int IA.Foo2()
{
Console.WriteLine("IA-Foo2 which retruns an integer.");
return 0;
}
string IB.Foo2()
{
Console.WriteLine("IA-Foo2 which retruns an string.");
return "";
}
}
public interface IA
{
string Foo(); //same return type
int Foo2(); //different return tupe
}
public interface IB
{
string Foo();
string Foo2();
}
}

Categories