C# implicit cast from base class to extended (System.Reflection.Assembly) - c#

I've been working the project mentioned c-sharp-compilerresults-generateinmemory.
I've been writing a lot of code to get my "class discovery" implemented. It works cool, but I realized it would be a lot more efficient if I implemented everything as an derived class of `System.Reflection.Assembly'.
So with that new derived class written I hit a problem. When I try to assign the base class to the new derived class it throws an error, just the normal did you miss an explicit cast error.
I thought C# did implicit casting for extended types?
So I have some source code like this...
Assembly asm = MyCompilerResults.CompiledAssembly(); /* this works */
Interface asmInterface = new Interface();
asmInterface = asm; /* bad */
asmInterface = (Interface)asm; /* bad */
public class Interface : Assembly {
public Interface() {} // I always just declare the empty constructor.
public void Helpermethod1() {}
public void Helpermethod2() {}
public void Helpermethod3() {}
};
So as it's only the second week I've been writing C# I have to ask...
How do I add the base class to my class?
The question here... Why can't I write an implicit operator from a Base class to a Derived class in C#?
This seems to indicate my casting should work unless I'm misunderstanding the answers.

I think you missunderstood something. What you are trying to achieve is to assign base class to derived one. It's not possible on almost every case.
Consider following:
public class A
{
}
public class B : A
{
}
A a = new B();
// some code
B b = (B)a; // it is possible. Behind the scenes, variable a is of B type.
but:
A a = new A();
B b = (B)a; //IT'S NOT ALLOWED. The variable a is of type A that has
// no "knowledge" about B class.
In your case, CompiledAssembly() returns Assembly instance that has no any information about Interface class, so it cannot be directly casted.
There are two options. Write wrapper:
public class Interface
{
private readonly Assembly underlyingAssembly;
publiic Interface(Assembly asm)
{
this.underlyingAssembly = asm;
}
// other methods
}
Assembly someAsm = MyCompilerResults.CompiledAssembly();
Interface interface = new Interface(someAsm);
or write extension methods:
public static class AsmExt
{
public static void SomeMethod(this Assembly asm)
{
}
}
Assembly someAsm = MyCompilerResults.CompiledAssembly();
someAsm.SomeMethod();

You may want to acchieve something different here, which can be done by using extensionmethods
You have to create a static class which then offers the functionality to extend the object like this:
public static class AssemblyExtension
{
public static void HelperMethod1(this Assembly asm)
{
Console.WriteLine(asm.ToString());
}
}
You can then call it like this:
Assembly asm = MyCompilerResults.CompiledAssembly();
asm.HelperMethod1();

Related

Use internal class as T in List<T>

Code:
Assembly with internal class (Example class)
internal class Abc
{
int a;
float pos;
}
How do i make a List<T> with T as internal class Abc?
It's an external assembly which means that I can't do InternalsVisibleTo, and the assembly isn't made by me so I can't just edit it.
I think the List<T> issue is a moot point. Really what you seem to be asking is "how do I expose an internal implementation to a public API?"
There are a few options for this:
Use an interface (if implementations are related by functionality)
Use an abstract class (if derived types are related by identity)
Use a base class (if derived types are related by identity and the base class may also be instantiated)
Example
Consider AbcBase and AbcInternal are in a separate assembly.
// Provides a publicly available class.
// Note, the internal default constructor will only allow derived types from the same assembly, meaning the class is essentially sealed to the outside world
public class AbcBase
{
internal AbcBase()
{
}
protected int a;
protected float pos;
public static List<AbcBase> CreateList()
{
return new List<AbcBase>()
{
new AbcInternal(1, 2.3f),
new AbcInternal(4, 5.6f)
};
}
}
internal sealed class AbcInternal : AbcBase
{
public AbcInternal(int a, float pos)
{
this.a = a;
this.pos = pos;
}
}
Consider Program is in the consuming assembly, or in other words, references the assembly where AbcBase and AbcInternal are implemented
class Program
{
static void Main(string[] args)
{
List<AbcBase> list = AbcBase.CreateList();
}
}
Note that the public implementation is exposed through AbcBase but not the internal implementation.
public class AbcImpl : AbcBase
{
}
Note, the above will cause a compiler error because the contructor in AbcBase is internal, therefore this class cannot be overridden from a different assembly.
'AbcBase.AbcBase()' is inaccessible due to its protection level
Provided you have a variable of the type Abc you can do the following:
// Get the value of type Abc with its runtime type.
var abc = ...;
// Variable listOfAbcs will be of type List<Abc>.
var listOfAbcs = CreateList(abs);
// Local function to create a list.
List<T> CreateList<T>(T value) => new List<T>();
Alternatively you can create a list with reflections and access it via IList interface.
You can't. internal restricts access to the type to only the containing assembly.

keep code organized using generic types

I like to keep things separate when programming. That is one of the reasons why inheritance is important I believe.
I am using a dll file that consists of a class that I cannot modify. the dll file contains ClassA to illustrate my example.
class Program
{
static void Main(string[] args)
{
ClassA object1 = new ClassA();
SomeMethod<ClassA>(object1 ); // error because " a does not implement ITemp"
}
static T SomeMethod<T>(T input)
where T:ITemp // make sure input has a method MyCustomMethod
{
input.MyCustomMethod();
return input;
}
// create this interface so that compiler does not complain when
// calling MyCustomMethod in method above
interface ITemp
{
void MyCustomMethod();
}
}
// classA is a sealed class in a dll file that I cannot modify
public class ClassA
{
public void MyCustomMethod()
{
}
}
why is there an error if object1 does implement ITemp inteface! object1 has the method MyCustomMethod()
I know I can use reflection to solve this but I like to keep my code clean. also I want to avoid using the dynamic type.
ClassA doesn't implement the ITemp interface. Just because it has a method with the same name and signature as the method in the ITemp interface doesn't mean it implements that interface. The class would need to be declared to implement it explicitly.
Since you can't extend ClassA, the best thing I can think of would be to wrap it with an adapter type class:
public ClassB : ITemp {
protected ClassA classAInstance;
public ClassB( ClassA obj ) {
classAInstance = obj;
}
public void MyCustomMethod() {
classAInstance.MyCustomMethod();
}
}
Then in your main method:
static void Main(string[] args)
{
ClassA object1 = new ClassA();
SomeMethod<ClassB>(new ClassB(object1));
}
You are trying to use duck typing. C# does not support that in general outside of the dynamic type. ClassA would need to implement the interface, as you noted it doesn't and can not be made to be. You could wrap class with a proxy but that may or may not be a good idea.

reference the "self" type in a static method - C#

I am trying to create a static method that would return an instance of the class, something like:
class A {
public static A getInstance() {
return new A();
}
}
The problem I am having is that if I have a subclass B derived from A, I would like B.getInstance() to return an instance of B, and not A. In PHP world, you could use a keyword "self" to reference to your own type, so your getInstance() would look like:
public static function getInstance() {
return new self();
}
What's the best way to go about this?
You can't, basically. If a call to a static member which is only declared in a base class is actually expressed in terms of the derived class, like this:
// Urgh
Encoding ascii = ASCIIEncoding.ASCII;
// Worse yet (and yes, I've seen this)
Encoding ascii = UTF8Encoding.ASCII;
then the compiler silently transforms that to:
Encoding ascii = Encoding.ASCII;
The fact that the original source contained the name of a derived class is not preserved in the compiled code, so it can't be acted on at execution time.
How about using generics to provide the type to produce:
public static T getInstance<T>() where T : A, new()
{
return new T();
}
You can hide and so in a way override the getInstance method in the inheriting type like this:
class B : A {
public static new B getInstance() {
return new B();
}
}
The new keyword specifies that the hiding of the inherited method was intentional, otherwise you get a compiler warning.
Complete example:
using System;
class A {
public static A getInstance() { return new A(); }
public void PrintSelf() {Console.WriteLine(this.GetType().Name);}
}
class B : A {
public static new B getInstance() {
return new B();
}
}
public class MyClass {
public static void Main() {
A a = A.getInstance();
B b = B.getInstance();
a.PrintSelf();
b.PrintSelf();
}
}
There's no way to do this statically -- you just have to use the actual name.
However, I'll bet PHP does this dynamically (i.e., with reflection) -- in which case you can always use GetCurrentMethod to get information about the method and itse enclosing type.
That way you can do something like:
using System.Reflection;
class Test
{
static object MakeTest()
{
return Activator.CreateInstance(
MethodBase.GetCurrentMethod().DeclaringType);
}
void Hello() { Console.WriteLine("Hi!"); }
static void Main()
{
dynamic test = MakeTest();
test.Hello();
}
}
Since others say there's no way to do this, I'll just offer up CRTP. It has its faults (Eric Lippert has a post about it here somewhere), but it will solve this problem
class Base<T> where T : Base<T>, new() {
public static T GetInstance() {
return new T();
}
}
class Derived : Base<Derived> {
}
Derived d = Derived.GetInstance();
This does make Base<T> hard to use, however. It's best if Base<T> is abstract. You can also create a side class like this that can actually be instantiated and used:
class Base : Base<Base> {
}
It looks weird, but it works. Unfortunately, Base and Derived will not be related anymore (except by Base<T>) so you can't cast between them, as such.
You can not override static member function in derived class. If you choose static approach, you need just add the same method to B class.
Sure you can use also different design patterns, like Factory for example, but I think this is out of scope of the question.

generic inheritance in C#? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why cannot C# generics derive from one of the generic type parameters like they can in C++ templates?
I can do
public class MyGenericClass : DL
//but i cannot do
public class MyGenericClass <T> : T
How would i do the second? if i cannot do that, how can i do something like
public class MyGenericClass <T>
{
T obj;
//have all MyGenericClass.XYZ call obj.XYZ
}
This is not possible, because depending on what type T is, the public interface of MyGenericClass would change.
If you have lots of different classes that all expose the same interface, you could declare MyGenericClass to expose that interface, and in the implementation of all of the functions delegate the calls to obj
The specific question, why can't you do this:
public class MyGenericClass<T> : T
And you can do this:
public class MyGenericClass<T>
{
T obj;
}
The reason is that the CLR likes to be able to compile a single version of the code for MyGenericClass that will work for any reference type specified for T.
It can do this for the second case, because it can quietly replace T with object and insert appropriate casts, roughly equivalent to:
public class MyGenericClass
{
object obj;
}
But for the inheritance version, that trick doesn't work.
Also, many useful facilities would be impossible to describe through interface constraints. When you inherit from a type, you can do a lot more than just call methods on it - you can override them as well. Consider this hypothetical example:
class MyBase
{
public virtual void MyVirtual() { }
}
class MyGenericDerived<T> : T
{
public override void MyVirtual()
{
Console.WriteLine("Overridden!");
}
}
MyBase obj = new MyGenericDerived<MyBase>();
obj.MyVirtual();
What I want to do there is something like a "mix-in", where MyGenericDerived supplies definitions for virtual functions in whatever base it is applied to. But how does the compiler know that T will have a method called MyVirtual that can be overridden? I'd need to put a constraint on T. How would I express that through interfaces? It's impossible. Using interfaces to describe constraints isn't an adequate solution once you allow inheritance from type parameters. So that's another reason why it doesn't exist in the language today.
You could do something like
public interface IXyzable { void xyz(); }
public class MyGenericClass<T> : IXyzable where T : IXyzable {
T obj;
public void xyz() {
obj.xyz();
}
}
Edit: Now I understand the question
You'll need all your possible T's to implement some interface so that you know that obj.XYZ() makes sense, then you can do
public interface Ixyz
{
void XYZ();
}
public class MyGenericClass<T> : Ixyz where T:Ixyz, new()
{
T obj;
public MyGenericClass()
{
obj = new T();
}
public void XYZ()
{
obj.XYZ();
}
}
I've made MyGenericClass implement Ixyz too since it obviously does expose the right method, but maybe that's best left out since it allows
var x = new MyGenericClass<MyGenericClass<SomeClass>>();
which is unlikely to ever be a good idea.
This is pretty much duck-typing, but you could use reflection.
When you create the generic class with a reference to the obj, use reflection to try and find a method with the right signature. As long as you store a reference to the method, performance won't be too bad.
class BaseGeneric<T>
{
private T obj;
private MethodInfo mi;
private const string MethodNameOfInterest = "Xyz";
public BaseGeneric(T theObject)
{
this.obj = theObject;
Type t = obj.GetType();
mi = t.GetMethod(MethodNameOfInterest);
}
public void Xyz()
{
mi.Invoke(obj, null);
}
}
Of course, you would need to add a lot more for error checking and such, but that is the gist of what you could do. Also, don't forget to add the System.Reflection namespace to your using clause.
The .NET type system won't allow type declarations of the form you're attempting. One reason why this is disallowed should be intuitive: how would MyGenericClass<T> act when T is a sealed class (e.g. System.String)?
If you absolutely need this functionality (and you know that the type T you'll be using isn't sealed), you can generate proxies at runtime using the classes in the Reflection.Emit namespace. It may also be possible to achieve this effect using AOP tools like PostSharp.
What about this:
class BaseClass<T>
{
public T property { get; set; }
}
class GenericClass<T> : BaseClass<T>
{
}
class Program
{
static void Main(string[] args)
{
GenericClass<int> l = new GenericClass<int>();
l.property = 10;
}
}
This achieves what you want to do?

Difference between shadowing and overriding in C#?

What's difference between shadowing and overriding a method in C#?
Well inheritance...
suppose you have this classes:
class A {
public int Foo(){ return 5;}
public virtual int Bar(){return 5;}
}
class B : A{
public new int Foo() { return 1;} //shadow
public override int Bar() {return 1;} //override
}
then when you call this:
A clA = new A();
B clB = new B();
Console.WriteLine(clA.Foo()); // output 5
Console.WriteLine(clA.Bar()); // output 5
Console.WriteLine(clB.Foo()); // output 1
Console.WriteLine(clB.Bar()); // output 1
//now let's cast B to an A class
Console.WriteLine(((A)clB).Foo()); // output 5 <<<-- shadow
Console.WriteLine(((A)clB).Bar()); // output 1
Suppose you have a base class and you use the base class in all your code instead of the inherited classes, and you use shadow, it will return the values the base class returns instead of following the inheritance tree of the real type of the object.
Run code here
Hope I'm making sense :)
Shadowing is actually VB parlance for what we would refer to as hiding in C#.
Often hiding (shadowing in VB) and overriding are shown as in answer by Stormenet.
A virtual method is shown to be overridden by a sub-class and calls to that method even on the super-class type or from inside code of the super-class will call the replacement implementation from the sub-class.
Then a concrete method is shown (one not marked as virtual or abstract) being hidden by using the new keyword when defining a method with an identical signature on the sub-class. In this case when the method is called on the super-class type the original implementation is used, the new implementation is only available on the sub-class.
However what is often missed is that it is also possible to hide a virtual method.
class A
{
public virtual void DoStuff() { // original implementation }
}
class B : A
{
public new void DoStuff() { //new implementation }
}
B b = new B();
A a = b;
b.DoStuff(); //calls new implementation
a.DoStuff(); //calls original implementation.
Note in the above example DoStuff becomes concrete and can not be overriden. However it is also possible to use both the virtual and new keywords together.
class A
{
public virtual void DoStuff() { // original implementation }
}
class B : A
{
public new virtual void DoStuff() { //new implementation }
}
class C : B
{
public override void DoStuff() { //replacement implementation }
}
C c = new C();
B b = c;
A a = b;
c.DoStuff(); //calls replacement implementation
b.DoStuff(); //calls replacement implementation
a.DoStuff(); //calls original implementation.
Note that despite all the methods involved being virtual, the override on C does not affect the virtual method on A because of the use of new in B hides the A implementation.
Edit: Its been noted in the comments to this answer that the above may be dangerous or at least not particularly useful. I would say yes it can be dangerous and would be out there if it were at all useful.
In particular you could get into all sorts of trouble if you also change the accessability modifiers. For example:-
public class Foo
{
internal Foo() { }
protected virtual string Thing() { return "foo"; }
}
public class Bar : Foo
{
internal new string Thing() { return "bar"; }
}
To an external inheritor of Bar, Foo's implementation of Thing() remains accesible and overridable. All legal and explainable according to .NET type rules neverless quite unintuative.
I've posted this answer to deepen an understanding of how things work not as a suggestion of techniques that can be used freely.
I think the main difference is that with shadowing, you're essentially reusing the name, and just ignoring the superclass use. With overriding, you're changing the implementation, but not the accessibility and signature (e.g. parameter types and return). See http://www.geekinterview.com/question_details/19331 .
Shadowing is a VB.NET concept. In C#, Shadowing is known as Hiding. It hides the derived class method. It is accomplished using the ‘new’ keyword.
Override keyword is used to provide a completely new implementation of a base class method (which is marked ‘Virtual’) in the derived class.
The answers above do not describe how to shadow/hide a base class' constructor. For completeness adding that special case here.
Say if you want to wrap ApplicationException in your own class MyApplicationException here is the syntax....
public class MyApplicationException : ApplicationException
{
public MyApplicationException(string message) : base(message)
{
// NOOP
} // constructor
public MyApplicationException(string message, Exception innerException) : base(message, innerException)
{
// NOOP
} // constructor
} // class MyApplicationException
Basically if you have something like below,
Class A
{
}
Class B:A
{
}
A a = new B();
Any method you call on the object 'a' will be made on the type of 'a'(Here the type is 'A')
But if you implement the same method in class B that is already present in Class A, the compiler will give you a warning to use a "New" keyword. If you use "New", the warning will disappear. Other than this there is no difference between using "New" or not using it in the inherited class.
In some situations you may need to call a method of the reference class the particular instance holds at that moment instead of calling a method on the object type. In the above case the reference it holds is 'B', but the type is 'A'. So if you want the method call should happen on 'B', then you use Virtual and override to achieve this.
Hope this helps...
Daniel Sandeep.
If there is a case in which you cannot alter the contents of a class, let's say A, but you want to use its some methods along with you have a method which name is common, you can use your own method implementation by the new keyword.
The crux point is to use it that both the reference and object must be of the same type.
class A
{
public void Test()
{
Console.WriteLine("base");
}
}
class B : A
{
public new void Test()
{
Console.WriteLine("sub");
}
public static void Main(string[] args)
{
A a = new A();
B aa = new B();
a.Test();
aa.Test();
}
}

Categories