I have a namespace that will change somewhat frequently in my project (each product generation) and would like to keep references to that specific namespace contained to the file where I define a base class. In other files I define child classes that usually can get by with getting references to the namespace by inheritance, but I am having trouble with one case as the objects are very specific and I would prefer to link to the namespace within the base class rather than each object.
BaseClass.cs
namespace CommonNameSpace
{
using _productSpecificNameSpace;
_productSpecificNameSpace.thing.otherthing thingotherthingGood = _productSpecificNameSpace.thing.otherthing.Success;
_productSpecificNameSpace.thing.otherthing thingotherthingBad = _productSpecificNameSpace.thing.otherthing.SpecificFailure;
public class BaseClass
{
}
}
SubClass.cs
namespace CommonNameSpace
{
public class SubClass : BaseClass
{
var yeaOrNeigh = thingotherthingGood
}
}
How can I access _productSpecificNameSpace in SubClass.cs without having to call it _productSpecificNameSpace in each subclass, or name every possible object that I will need in BaseClass? Is there a way to get an alias to a namespace attached to a class for inheriting?
Edit: Ideally, I would like to have access to the data types in the interchangeable namespace, as it is mostly a library of enums. Wouldn't having an interface replace the type of these enums with an interface type that would be incomparable with calls to APIs expecting the underlying type?
If you use an interface, you can then instantiate the generation you want to at runtime, without affecting any existing code:
interface IMyThing
{
void DoStuff()
}
abstract class BaseThing : IMyThing
{
public virtual void DoStuff()
}
Generation1:
class MyGen1 : BaseThing
{
public override void DoStuff()
{
// I'm Gen 1
}
}
Generation2:
class MyGen2 : BaseThing
{
public override void DoStuff()
{
// I'm Gen 2
}
}
Related
Consider the following code:
using System;
namespace Nesting
{
class Program
{
static void Main()
{
new Nested.Class().Method();
}
}
namespace Nested
{
internal class Class
{
internal void Method()
{
Console.WriteLine("Inside Method");
}
}
}
}
The output:
Inside Method
Which means that Nesting members are allowed to access internal members of Nested. Is there a way to force members of Nested to be visible only to other Nested members?
In short, Not within the same assembly.
Unlike Java, the internal accessibility (Friend in VB.Net) is to make the class/member only visible within the same assembly.
Strictly speaking the using reflection, you could still get to the hidden bits in another assembly.
An alternate scenario would be to use nested classes (rather than namespaces), so something like:
internal class Nested
{
protected class Class
{
// Only usable from the Nested class
internal void Method()
{
Console.WriteLine("Inside Method");
}
}
}
}
No, you can't. All three relevant access modifiers don't give what you want. There is no way to enforce this without pulling the nested class to another assembly.
I have got a partial class in my C# project i.e. auto-generated code from Entity Framework. Now I want to modify or add some more functionalities, properties or methods to that class. I have the auto-generated class code under EntityFrameworkModel.tt\Author.cs tab in the project while the other related classes are in another folder i.e. GraphData in the same project.
I also know that the name of partial classes should be same while file name may be different or same as well. I did same but when I defined the object for Author.cs as:
protected override EvoObject ConvertCPV(Author _author)
{
if (_author.???)
{
//...
}
}
I can't access the methods defined in GraphData\Author.cs (The question marks in example code) whereas the properties defined in EntityFrameworkModel.tt\Author.cs are only accessible.
Here I attached the Solution Explorer image as:
How can I access the properties and methods from both classes?
I have a similar set up in a project also.
To keep things tidy I also have folders where I place certain partial classes, you just need to ensure the namespace is the same as the auto generated class.
When you add a new class to a folder the namespace will automatically contain the name of the folder - you can just remove the folder name from the namespace - you should just have the Project name in this scenario.
If the namespaces are different then the partial classes are not part of the same class. This is why you can't access the new functions/Properties.
Also, even though your file name and class names can be different, it is better to keep them the same - it will be easier to find a class if the file has the same name.
Check out https://msdn.microsoft.com/en-us/library/wa80x488.aspx
It says "The partial keyword indicates that other parts of the class, struct, or interface can be defined in the namespace." It does not explicitly state this, but that implies that the partial definitions of the class must be declared in the same namespace. It doesn't matter which files in the project contain the classes, or what folders they are in.
using System;
namespace DemoConsoleApp
{
class Program
{
static void Main(string[] args)
{
SameNamespace.PartialClass.MethodOne();
SameNamespace.PartialClass.MethodTwo();
DifferentNamespace.PartialClass.MethodThree();
}
}
}
namespace SameNamespace
{
public partial class PartialClass
{
public static void MethodOne()
{
Console.WriteLine("Method One.");
}
}
public partial class PartialClass
{
public static void MethodTwo()
{
Console.WriteLine("Method Two.");
}
}
}
namespace DifferentNamespace
{
public partial class PartialClass
{
public static void MethodThree()
{
Console.WriteLine("Method Three.");
}
}
}
Make your own class outside of EntityFrameworkModel.tt - name it Author.cs, make the class partial.
The whole idea of partial is to allow code generators not to care about your code. Of you modify a generated class, the next regeneration kills the changes.
I did same but when I defined the object for Author.cs as:
Ah, no, you did not because then you claim your definition is:
protected override EvoObject ConvertCPV(Author _author)
Which is NOT defining the object.
I can't access the methods defined in GraphData\Author.cs
Because namespace? Check the namespaces - bad to have them in a subfolder when they belong in a the same namespace as EntityFrameworkModel.tt
whereas the properties defined in EntityFrameworkModel.tt\Author.cs are only
accessible.
Partial classes do not allow changes in another partial - not for the moment, a substition syntax is considered.
my last problem is with inheritance in C#. I thought I understood this topic but somehow I am missing the point why the output is like that.
Here are my classes:
BaseClass:
public abstract class Vehicle
{
public Vehicle()
{
Console.WriteLine("Honda Civic");
}
public abstract void Display();
}
Derived Class 1:
public class Vehicle4Wheels : Vehicle
{
public override void Display()
{
Console.WriteLine("Derived111 class Constructor.");
}
}
Derived Class 2:
public class SportCar : Vehicle4Wheels
{
public new void Display()
{
Console.WriteLine("Derived222 class Constructor.");
base.Display();
}
}
This is the hierarchy: Base Class -> Derived Class 1 -> Derived Class 2
This is the output I am getting:
Honda Civic
Derived222 class Constructor.
Derived111 class Constructor.
This is the output I am trying to achieve:
Honda Civic
Derived111 class Constructor.
Derived222 class Constructor.
I have read several articles where it was stated that base class is printed first and the other derived classes are printed based on their spot in the hierarchy.
So why is the last derived class printed before the first derived class? What am I missing (except C# programming skills)?
Thank for the answers.
EDIT:
I am sorry it took me a while to get back to this thread. To be more precise, I will post the task of the homework I am trying to achieve:
Work 2:
An abstract class is not a complete class, it misses some parts, and you cannot create
objects from it. The programmer who writes the derived classes must fill in the missing
parts. Consider an abstract class Vehicle. Derive two hierarchies from this class as it
is shown below: Now, write 4 classes, see the yellow rectangle. Start from the abstract
base class Vehicle -> Vehicle with 4 wheels -> Sport Cars and stop at the derived class Rally, which is the most specific
class. The class Vehicle contains a field which holds the vehicle name and an abstract
method void Display().
Implement this function in the derived classes, so that the function returns
information about the vehicle, e.g. the motor power and other necessary properties. The
last derived class has private fields to hold the motor power, the car weight, the car
acceleration, the highest speed and a function that computes the specific power (power
/ weight). The function Display returns a text string with all this information. Test
your work in a Console application that uses objects of the type of the classes Sport
car and Rally.
Class Vehicle:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace A_work_2
{
public abstract class Vehicle
{
public string vehicleName;
public abstract void Display();
}
}
Class Vehicle4Wheels:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace A_work_2
{
public class Vehicle4Wheels : Vehicle
{
public override void Display()
{
Console.WriteLine("Car1");
}
}
}
Class SportCar:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace A_work_2
{
public class SportCar : Vehicle4Wheels {
public override void Display()
{
Console.WriteLine("Derived222 class Constructor.");
}
}
}
Class Rally:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace A_work_2
{
public class Rally : SportCar
{
private double motorPower = 408;
private double carWeight = 2380;
private double carAcceleration = 4.7;
private double highestSpeed = 250;
public double SpecificPower()
{
double specificPower = motorPower / carWeight;
return specificPower;
}
public override void Display()
{
Console.WriteLine("The acceleration is: {0}.\nThe highest speed is {1} km/h.", carAcceleration, highestSpeed);
Console.WriteLine("Specific power is {0}", SpecificPower());
}
}
}
I am not sure how to achieve the goal of the task with abstract methods.
Thank you for answers, V.
You are mixing the concept of a constructor with the concept of a virtual method. Constructors are indeed called in order from base to derived, but you have created non-constructor virtual methods.
This will give the output you wanted:
// In Vehicle4Wheels
public Vehicle4Wheels()
{
Console.WriteLine("Vehicle4Wheels constructor");
}
// In SportCar
public SportCar()
{
Console.WriteLine("SportCar constructor");
}
(Also, edit the string you are printing in the Display() methods, since they are misleading - Display() is not a constructor.)
As for virtual methods (note that abstract methods automatically become virtual), the "most derived" class' method is the one that is called, and only that method is called - unless the method invokes base.MethodName().
This is the output I am getting: Honda Civic Derived222 class
Constructor. Derived111 class Constructor.
This is the output I am trying to achieve: Honda Civic Derived111
class Constructor. Derived222 class Constructor.
Ok, just swap the calls:
public new void Display()
{
base.Display();
Console.WriteLine("Derived222 class Constructor.");
}
You first Get Honda Civic because it is output during the creation of the base class. the constructors of the base class is the first thing that is perform during the constructor of the inherited class.
Then you Get Derived222 because it is output first in your display method.
Change your code that way :
public abstract class Vehicle {
public Vehicle() { Console.WriteLine("Honda Civic"); }
}
public class Vehicle4Wheels : Vehicle {
public Vehicle4Wheels() { Console.WriteLine("Derived111 class Constructor."); }
}
public class SportCar : Vehicle4Wheels {
public SportCar() { Console.WriteLine("Derived222 class Constructor.");
}
you don't need to override the Display() method in what you(re trying to achieve.
And beware of the use of the new keyword when declaring a method ;-)
You didn't show the code you are using to test your classes, but I think it is something like this:
SportCar car = new SportCar();
car.Display();
The first thing that is not so clear is why you are writing on the console in the constructor of the abstract class, but in a method of the derived ones. This means that, apart from the order of the messages, Honda Civic is written as soon as you create an instance of each one of your classe, while the other messages are written only when you call the Display method (even if you write Constructor in the method).
#Seb gave you the right way to go if you want to do specific things in the constructors of a hierarchy of classes, but if you really wanted to write different versions of the method Display, you must be careful to the use of override and new. If a method is virtual or abstract, you should always use override, and leave the use of new to the cases in which you want to hide the method defined in the base classes. You can find an example (using cars like you :-)) here: [http://msdn.microsoft.com/en-us/library/ms173153(v=vs.80).aspx].
If you use override, the method being executed is determined at run time and depends on the type of the object. If you use new the method being executed is determined at compile time and depends on the type of the variable you assign your object to. For instance, if you execute this piece of code with your classes:
Console.WriteLine("This is the constructor");
SportCar car = new SportCar();
Console.WriteLine("This is the first call to display");
car.Display();
Vehicle4Wheels car2 = car;
Console.WriteLine("This is the second call to display");
car2.Display();
The result is:
This is the constructor
Honda Civic
This is the first call to display
Derived222 class Constructor.
Derived111 class Constructor.
This is the second call to display
Derived111 class Constructor.
Replacing the new with an override you obtain what you are probably expecting:
This is the constructor
Honda Civic
This is the first call to display
Derived222 class Constructor.
Derived111 class Constructor.
This is the second call to display
Derived222 class Constructor.
Derived111 class Constructor.
Is it possible to select a namespace for classes at runtime. We have two copies of auto generated objects in different namespaces. Here is an example:
Namespace1
ClassA
ClassB
Namaspace2
ClassA
ClassB
Formerly, the code is simple like below
using Namespace1
...
ClassA.AMethod()
However, we need to select namespace at runtime using a condition variable. Is there a way to define a GetNamespace() method and use it like below or is there any other way you recommend?
GetNamespace().ClassA.AMethod()
Cheers,
Burak
As far as I know, there is no way to dynamically select the namespace, but I think you're in the perfect situation to use a factory. To do so, all your A classes must derive from an abstract one:
namespace Common {
public abstract class AbsA
{
//...
}
public class MyFactory
{
public MyFactory()
{
//...
}
public AbsA getA()
{
AbsA a;
if (condition)
a = new Namespace1.A();
else
a = new Namespace2.A();
return a;
}
}
}
Then you ask your factory for object creation:
MyFactory factory = new MyFactory();
labelMessage.Text = factory.getA().Something;
This complicates your structure a bit, but also makes it more coherent.
Two types from different namespaces are entirely different types as far as the CLR is concerned. Basically you'd need to consider the same solutions as you would for picking between any other arbitrary types... e.g. making both classes implement the same interface, and instead of GetNamespace() returning a namespace, it would have to return the object itself.
Given that you can:
var type = Type.GetType("Namespace1.ClassA");
object instance = Activator.CreateInstance(type);
If you then want to invoke methods on that instance, you need to either cast it to a common interface, or get a MethodInfo instance to invoke. If you control the generation of the classes, I would recommend the interface approach:
public interface IClassA
{
void AMethod();
}
namespace Namespace1
{
public class ClassA : IClassA
{ /* Stuff... */ }
}
That way, you need only:
var type = Type.GetType("Namespace1.ClassA");
IClassA instance = (IClassA)Activator.CreateInstance(type);
instance.AMethod();
Most autogenerated classes using tools such as Linq-to-Sql, Entity Framework, and even WCF proxies are created as partial, which means you can create an additional file, e.g. ClassA.partial.cs and add more to your class declarations without modifying the auto-generated class:
partial class ClassA : IClassA { }
How do I Load the class "MyContent" dynamically ?
I have 1 interface<T>, 1 abstract generic class<T> and 1 class. Check my code out:
public interface IMyObjectInterface{
}
public abstract MyAbstractObject : IMyObjectInterface{
}
public class MyObject : MyAbstractObject{
}
public interface IMyContentInterface<T> where T : MyAbstractObject
{
void MyMethod();
}
public abstract MyAbstractContent<T>, IMyContentInterface<T> where T : MyAbstractObject
{
public abstract void MyMethod();
}
public public class MyContent : MyAbstractContent<MyObject>
{
public override void MyMethod() { //do something }
}
I am trying but obviously it's not working:
IMyObjectInterface obj = (IMyObjectInterface)Assembly.Load("MyAssembly").CreateInstance("MyObject");
IMyContentInterface<obj> content = (IMyContentInterface<obj>)Assembly.Load("MyAssembly").CreateInstance("MyContent");
content.MyMethod();
//assembly and type names are correct
If I change IMyContentInterface<obj> to IMyContentInterface<MyObject>, works :
IMyContentInterface<MyObject> content = (IMyContentInterface<MyObject>)Assembly.Load("MyAssembly").CreateInstance("MyContent");
content.MyMethod();
//assembly and type names are correct
The problem is that i don't what is going to be my object in the 2nd line, when defining IMyContentInterface<T>. Please, does somebody know how to do it in .NET Framework 4.0?
the item in the < > has to be a type not an object.
my car is an object of the type car so
Car myCar=new Car();
i want a list to keep my cars (objects of type Car) in.
List<Car> myCars = new List<Car>();
And then we add object of type Car to my List.
myCars.Add(myCar);
myCars.Add(anotherCar);
How do I Load the class "MyContent" dynamically?
Loading it isn't hard - you already know how to do that, but C# generics are strongly-typed, checked and guaranteed at compile time. Consider this code:
List<string> list = new List<string>();
list.Add(new TcpSocket()); // This line won't compile
The C# compiler couldn't tell you this was illegal if you were allowed to declare generics like this:
Type type = GetTypeFromReflectedAssembly();
List<type> list = new List<type>();
// This *might* work - who knows?
list.Add(new TcpSocket());
If your ultimate goal is to call MyContent.MyMethod() and that doesn't have anything to do with the generic type parameter <T>, consider declaring a non-generic interface you can implement somewhere in your inheritance hierarchy and declare your instance variable using that:
IMyContentInterface content = (IMyContentInterface)Assembly.Load("MyAssembly").CreateInstance("MyContent");
content.MyMethod();
I had to read this a few times, but I figured out what you're asking. :) This question is a specific instance of this other question:
Pass An Instantiated System.Type as a Type Parameter for a Generic Class
That said, here's an example of how you might use it for your test case. Obviously you can vary it. Also, don't miss my final note at the end of this answer.
Assembly MyCompany.MyProduct.MyComponent:
Define your interfaces in this assembly:
namespace MyCompany.MyProduct.MyComponent
{
public interface IMyObjectInterface
{
void MyObjectMethod();
}
/* It's important to include this non-generic interface as a base for
* IMyContentInterface<T> because you will be able to reference this
* in the assembly where you load components dynamically.
*/
public interface IMyContentInterface
{
Type ObjectType
{
get;
}
void MyContentMethod();
}
public interface IMyContentInterface<T> : IMyContentInterface
where T : IMyObjectInterface
{
}
}
Assembly MyCompany.MyProduct.MyComponent.Implementation:
Implement the interfaces in this assembly that will be dynamically loaded.
namespace MyCompany.MyProduct.MyComponent
{
public abstract class MyAbstractObject : IMyObjectInterface
{
public abstract void MyObjectMethod();
}
public class MyObject : MyAbstractObject
{
public override void MyObjectMethod() { }
}
public abstract class MyAbstractContent<T> : IMyContentInterface<T>
where T : MyAbstractObject
{
public Type ObjectType
{
get
{
return typeof(T);
}
}
public abstract void MyContentMethod();
}
public class MyContent : MyAbstractContent<MyObject>
{
public override void MyContentMethod() { }
}
}
Assembly MyCompany.MyProduct
Your program is composed in this assembly, a term I pulled from the Managed Extensibility Framework. This assembly references MyCompany.MyProduct.MyComponent but not MyCompany.MyProduct.MyComponent.Implementation under the assumption that the interfaces are more likely to remain compatible than the implementations during product development. This design is an attempt to favor cohesion over coupling (a pair of often misunderstood words), but the actual implementations tend to vary heavily in their success of achieving this goal.
namespace MyCompany.MyProduct
{
using MyCompany.MyProduct.MyComponent;
using System.Reflection;
using System.Security.Policy;
public class ComponentHost
{
public void LoadComponents()
{
Assembly implementation = LoadImplementationAssembly();
/* The implementation assembly path might be loaded from an XML or
* similar configuration file
*/
Type objectType = implementation.GetType("MyCompany.MyProduct.MyComponent.MyObject");
Type contentType = implementation.GetType("MyCompany.MyProduct.MyComponent.MyContent");
/* THIS assembly only works with IMyContentInterface (not generic),
* but inside the implementation assembly, you can use the generic
* type since you can reference generic type parameter in the source.
*/
IMyContentInterface content = (IMyContentInterface)Activator.CreateInstance(contentType);
}
private Assembly LoadImplementationAssembly()
{
/* The implementation assembly path might be loaded from an XML or
* similar configuration file
*/
string assemblyPath = "MyCompany.MyProduct.MyComponent.Implementation.dll";
return Assembly.LoadFile(assemblyPath);
}
}
}
Final Note:
The Managed Extensibility Framework was built as a common solution to the problem you are working on. Having worked with it for a while now, I say with confidence that it has the following nice properties:
Relatively short learning curve.
Very clean code as a result.
Low runtime cost (the assembly is small and performance is quite good).
I would easily recommend it as serious viable option for someone working on a new application if it meets any combination of one or more of the following:
The application is divided into components (as almost any non-trivial application would be).
The application needs to be flexible or extensible in the future (as any long-term project would be).
The application needs to dynamically load an implementation from an unknown assembly.
This is a way to dynamically load a Interface. This assumes you have some way of getting the assembly you are trying to load it from and a string for the name of the type.
In my case I used an Xml file. You can use any, I don't show those methods, because it can change per your implementation.
ISomeInterface myInterface = this.GetComponent<ISomeInterface>("SomeImplementation");
public T GetComponent<T>(string componentName)
{
// A method to dymanicly load a .dll, not shown in this example
Assembly assembly = this.GetComponentAssembly(componentName);
// A method to get a string assembly type, in this case from another source
string assemblyType = this.GetAssemblyType(componentName);
T component = (T)assembly.CreateInstance(assemblyType);
return component;
}