Changing a class's property from another class - c#

I have a class with properties:
public class TaskConfiguration
{
public string Task_Name
{
get; set;
}
public string task_id
{
get; set;
}
}
And somewhere in the code I have a method to set the properties of the class early on upon program execution:
public class TaskManagingProcess
{
public void InsertTaskProperties()
{
TaskConfiguration tc = new TaskConfiguration();
tc.Task_Name = "Sample Task";
tc.task_id = "1";
}
}
Later in execution, in another class, I want to modify the properties of the TaskConfiguration class, but I'm not sure how. If I use the following, it will not work because it creates a new instance of the TaskConfiguration class.
TaskManagingProcess tmp = new TaskManagingProcess;
tmp.InsertTaskProperties();
So how can I do this?

You want to pass the object:
public void InsertTaskProperties(TaskConfiguration config) {
config.Task_Name = "Sample Task";
config.task_id = "1";
}
Then:
TaskManagingProcess tmp = new TaskManagingProcess();
TaskConfiguration config = new TaskConfiguration();
tmp.InsertTaskProperties(config);
(I am making an awfully large assumption about your code.. but this should give you the basic idea)

It looks to me like TaskManagingProcess is a proxy class that's why I would recommend something like:
public class TaskConfiguration
{
public string Task_Name
{
get;
set;
}
public string task_id
{
get;
set;
}
}
public class TaskManagingProcess
{
private TaskConfiguration taskConfiguration;
public TaskManagingProcess(TaskConfiguration taskConfiguration)
{
this.taskConfiguration = taskConfiguration;
}
public void InsertTaskProperties(string taskId, string name)
{
taskConfiguration.task_id = taskId;
taskConfiguration.Task_Name = name;
}
}
So at the end you could do this (see below) and easily add code to handle the access at your TaskConfiguration object:
TaskConfiguration taskConfiguration = new TaskConfiguration() { task_id = "1", Task_Name = "Sample Task" };
TaskManagingProcess taskManaginProcess = new TaskManagingProcess(taskConfiguration);
taskManaginProcess.InsertTaskProperties("2", "Sample Task 2");

Related

setting a static variable in a static class depending on the calling class

Static class code :
static public class CommonValues
{
public static string _consumerName;
}
Assigning from a non-static class :
public class CreateSessionConsumer : IClassFixture<CommonFixture>
{
private IMockProviderService _mockProviderService;
private string _mockProviderServiceBaseUri;
public string _path = "/Security/CreateSession";
public CreateSessionConsumer(CommonFixture fixture)
{
Common.CommonValues._consumerName = "CreateSessionConsumer";
Common.CommonValues._providerName = "CreateSessionAPI";
_mockProviderService = fixture.MockProviderService;
_mockProviderService.ClearInteractions(); //NOTE: Clears any previously registered interactions before the test is run
_mockProviderServiceBaseUri = fixture.MockProviderServiceBaseUri;
CommonFixture.PactDirectory=#"..\pacts";
//CommonFixture.Provider=_provider;
}
}
Accessing in this static variable in a generic method:
public class CommonFixture : IDisposable
{
public IPactBuilder PactBuilder { get; private set; }
public IMockProviderService MockProviderService { get; private set; }
public int MockServerPort { get { return 9222; } }
public string MockProviderServiceBaseUri { get { return String.Format("http://localhost:{0}", MockServerPort); } }
public static string PactDirectory { get; set; }
public CommonFixture()
{
var pactConfig = new PactConfig
{
SpecificationVersion = "2.4.6",
PactDir = #"..\..\..\..\..\pacts",
LogDir = #".\pact_logs"
};
PactBuilder = new PactBuilder(pactConfig);
PactBuilder.ServiceConsumer(Common.CommonValues._consumerName)
.HasPactWith(Common.CommonValues._providerName);
MockProviderService = PactBuilder.MockService(MockServerPort);
}
}
Issue is, CreateSessionConsumer class is not assigning the static variable. And CommonFixture is accessing a unassigned variable.
This could not be handled the way I have asked here. Eventually had to implement Fixture class along with each class file, which sets the consumername and providername individually.

How to acces an instance of a class from another class?

I have the following code:
public class UnitManager
{
public string Name { get; set; }
public string Firstname { get; set; }
public UnitManager(string name, string firstname)
{
this.Name = name;
this.Firstname = firstname;
}
}
class Other
{
}
class Program
{
static void Main(string[] args)
{
var player1 = new UnitManager("p1Name", "p1FirstName");
var player2 = new UnitManager("p2Name", "p2FirstName");
}
}
So, I have created 2 objects in the Program class.
what I'd like to do is access those instances from inside the Other class to // do stuff.
For example, access player name, put a title in his name, then assess player2 and put another title.
please, keep in mind, this is just an exemple, i'm not actually planning on using this, i'm just trying to grasp the concept.
I think you can write UnitManager a property in Other class, set the UnitManager
public class Other
{
public UnitManager manager1{ get; set; }
}
or write a method the pass UnitManager instance as parameter.
public class Other
{
public void SetTitle(UnitManager m1) {
// do your logic
}
}
Thank you all, i finally understood :)
Here's how i got it working with your help:
public class UnitManager
{
public string Name { get; set; }
public string Firstname { get; set; }
public UnitManager(string name, string firstname)
{
this.Name = name;
this.Firstname = firstname;
}
}
class Other
{
public static void AddTitle(UnitManager myUnit)
{
var titlePlusFullName = ("The Legendary" + " " + myUnit.Name + " " + myUnit.Firstname);
myUnit.Name = titlePlusFullName;
}
}
class Program
{
static void Main(string[] args)
{
var player1 = new UnitManager("john", "smith");
var player2 = new UnitManager("jen", "doe");
Other oT = new Other();
Other.AddTitle(player1);
Console.WriteLine("Player 1 name: " + player1.Name);
}
}
it displays full name + title.
I think you might want something like this:
public class UnitManager
{
public string Name { get; set; }
public string Firstname { get; set; }
public UnitManager(string name, string firstname)
{
this.Name = name;
this.Firstname = firstname;
}
}
public class Other
{
public void doSomething(UnitManager myUnit) {
//do something with each unit manager
}
}
public class Program
{
static void Main(string[] args)
{
//create an object of type UnitManager and place it into variable player1
var player1 = new UnitManager("p1Name", "p1FirstName");
//create an object of type UnitManager and place it into variable player2
var player2 = new UnitManager("p2Name", "p2FirstName");
//create an instance of the class Other
Other ot = new Other();
//call the method within the instantiated class ot (of type Other) and
//pass it the instance of the object UnitManager with a name
//of player1
result1 = ot.doSomething(player1);
result2 = ot.doSomething(player2);
}
}
If you have exactly 2 instances (players), why not create them within UnitManager?
// sealed: since we have 2 instances only we don't want to
// inherit (and create) derived classes
public sealed class UnitManager
{
public string Name { get; set; }
public string Firstname { get; set; }
// private: since we have 2 intances only we don't want to expose the constructor
private UnitManager(string name, string firstname)
{
this.Name = name;
this.Firstname = firstname;
}
// Think over renaming these fields: say, Player and Computer
public static readonly UnitManager Player1 = new UnitManager("p1Name", "p1FirstName");
public static readonly UnitManager Player2 = new UnitManager("p2Name", "p2FirstName");
}
Then address them as UnitManager.Player1 (UnitManager.Player2) e.g.
class Program
{
static void Main(string[] args)
{
UnitManager.Player1.Name = "First Name";
UnitManager.Player2.Name = "Second Name";
...
}
}
Or even (with a help of static import):
using static MyNamepace.UnitManager;
...
class Other
{
public void DoSomething()
{
// We don't have now put it as UnitManager.Player1
string name1 = Player1.Name;
...
}
}

How to share a list of objects without giving ability to modify their state?

Let's say I have a class StockMarket which has a list of Companies.
class StockMarket : IStock
{
private static List<IObserverPush> observersPush;
private static List<IObserverPull> observersPull;
public static List<Company> Companies { get; private set; }
public StockMarket()
{
observersPush = new List<IObserverPush>();
observersPull = new List<IObserverPull>();
Companies = new List<Company>() { new Company("Unilever", "UNA", 47.72, 0.77, 1.63, -3.45, "135B"),
new Company("ING Groep", "INGA", 13.40, -0.07, -0.50, -12.38, "60.4B"),
new Company("ArcelorMittal", "MT", 29.50, 0.14, 0.48, 36.05, "54.6B"),
new Company("ASML Holding", "ASML", 167.40, 2.00, 1.21, 36.49, "53.3B"),
new Company("Heineken", "HEIA", 87.66, -0.02, -0.02, 2.80, "49B"),
new Company("RELX", "REN", 18.15, 0.17, 0.95, -0.22, "38.9B"),
new Company("Philips", "PHIA", 35.49, 0.17, 0.47, 7.61, "33.3B"),
new Company("Unibail Rodamco", "UL", 196.40, -0.15, -0.08, -16.78, "20.3B"),
new Company("Akzo Nobel", "AKZA", 75.68, -0.16, -0.21, 0.33, "19.4B"),
new Company("Altice", "ATC", 7.58, 0.16, 2.16, -66.30, "17.6B")};
Thread thread = new Thread(SimulateMarket);
thread.Start();
}
public void Subscribe(IObserverPull o)
{
observersPull.Add(o);
o.UpdateMarket();
}
public void Unsubscribe(IObserverPull o)
{
observersPull.Remove(o);
}
public void Subscribe(IObserverPush o)
{
observersPush.Add(o);
o.UpdateMarket(Companies);
}
public void Unsubscribe(IObserverPush o)
{
observersPush.Remove(o);
}
public void NotifyObservers()
{
foreach(IObserverPush o in observersPush)
{
o.UpdateMarket(Companies);
}
foreach(IObserverPull o in observersPull)
{
o.UpdateMarket();
}
}
public void SimulateMarket()
{
while(observersPush.Count + observersPull.Count > 0)
{
//randomly change property values of companies
//and notify the observers about the changes
}
}
}
Company class has some properties.
public class Company
{
public string Name { get; private set; }
public string Symbol { get; private set; }
public double Price { get; set; }
public double Change { get; set; }
public double ChangePercentageDay { get; set; }
public double ChangePercentageYear { get; set; }
public string Capital { get; private set; }
public Company(string name, string symbol, double price, double change, double changePercentageDay,
double changePercentageYear, string capital)
{
Name = name;
Symbol = symbol;
Price = price;
Change = change;
ChangePercentageDay = changePercentageDay;
ChangePercentageYear = changePercentageYear;
Capital = capital;
}
}
The Forms have references to the StockMarket and they use it to retrieve data about the companies and to display it.
Form 1
public partial class ConcreteObserverPush : Form, IObserverPush
{
private StockMarket stockMarket;
public ConcreteObserverPush()
{
InitializeComponent();
stockMarket = new StockMarket();
stockMarket.Subscribe(this);
}
public void UpdateMarket(List<Company> companies)
{
stockMarketListView.Items.Clear();
foreach(Company c in companies)
{
ListViewItem item = new ListViewItem(c.Symbol);
item.SubItems.Add(c.Price.ToString());
item.SubItems.Add(c.Change.ToString());
item.SubItems.Add(c.ChangePercentageDay.ToString() + "%");
stockMarketListView.Items.Add(item);
}
}
private void ConcreteObserverPush_FormClosing(object sender, FormClosingEventArgs e)
{
stockMarket.Unsubscribe(this);
}
}
Form 2
public partial class ConcreteObserverPull : Form, IObserverPull
{
private StockMarket stockMarket;
public ConcreteObserverPull()
{
InitializeComponent();
stockMarket = new StockMarket();
stockMarket.Subscribe(this);
}
public void UpdateMarket()
{
stockMarketListView.Items.Clear();
foreach (Company c in StockMarket.Companies)
{
ListViewItem item = new ListViewItem(c.Symbol);
item.SubItems.Add(c.Name);
item.SubItems.Add(c.Price.ToString());
item.SubItems.Add(c.Change.ToString());
item.SubItems.Add(c.ChangePercentageDay.ToString() + "%");
item.SubItems.Add(c.ChangePercentageYear.ToString() + "%");
item.SubItems.Add(c.Capital);
stockMarketListView.Items.Add(item);
}
}
private void ConcreteObserverPull_FormClosing(object sender, FormClosingEventArgs e)
{
stockMarket.Unsubscribe(this);
}
}
The problem is that if the Form gets the list of companies through the property on StockMarket it can change their state. However, I want only StockMarket to have the ability to change the state of the company.
So what would be the best way to share Company state with Form when requested and preventing the Form from modifying it.
I know that a possible solution would be to return clones of Company objects, but I believe there should be a better solution.
Any help is appreciated!
The general gist of this would be to make your Company object immutable. Then you would add methods to the StockMarket object to manipulate the Company list and replace entries with new ones when you want to change a value.
Here's a quick example put together in LINQPad of making the Company class immutable and adding an UpdatePrice method to the StockMarket class.
Whether you want to be able to manipulate the Companies property from outside the StockMarket can be handled by returning the list as ReadOnlyCollection so that it's size can't be manipulated by a consumer.
void Main()
{
var sm = new StockMarket();
sm.Companies.Add(new Company("Test", "TST", 50, 0));
sm.UpdatePrice("Test", 45);
var testCompany = sm.Companies.First(x => x.Name == "Test");
Console.WriteLine($"{testCompany.Name},{testCompany.Symbol},{testCompany.Price},{testCompany.Change}");
//Output: Test,TST,45,-5
}
class StockMarket
{
public List<Company> Companies { get; private set; } = new List<Company>();
public void UpdatePrice(string name, double price) {
var index = Companies.FindIndex(x => x.Name == name);
if(index >= 0)
{
var previous = Companies[index];
Companies[index] = new Company(previous.Name, previous.Symbol, price, price - previous.Price);
}
}
}
class Company
{
public Company(string name, string symbol, double price, double change) {
Name = name;
Symbol = symbol;
Price = price;
Change = change;
}
public string Name { get; }
public string Symbol { get; }
public double Price { get; }
public double Change { get; }
///...
}
This would be a solution:
Create the Company class as a Private Inner Class inside of the StockMarket class, that way it'd only be accessible inside of it, and then provide an interface that only includes the get of all the properties and make Company implement it. You would have to make StockMarket's Company list to be the Interface's type.
Any modification you'd have to do you'd do it by casting the interface's List objects into the original class type.
Example:
class Program
{
public static StockMarket stockMarket = new StockMarket();
static void Main(string[] args)
{
}
}
public interface ICompany
{
string Name { get; }
}
public class StockMarket
{
public StockMarket()
{
Companies = SomeWildFunctionThatRetrievesAllCompanies();
}
public void OneWildFunctionThatModifiesACompany()
{
Company dunno = (Company)Companies[0];
dunno.Name = "Modification Made Possible";
}
private List<ICompany> SomeWildFunctionThatRetrievesAllCompanies()
{
return new List<ICompany>(new List<Company>());
}
public List<ICompany> Companies { get; private set; }
private class Company : ICompany
{
public string Name { get; set; }
}
}
Try this:
class Company
{
public Company(Type type,string name,string symbol,double price, double change)
{
if (type.Name == "StockMarket")
{
Name = name;
Symbol = symbol;
Price = price;
Change = change;
}
}
private string Name { get; set; }
private string Symbol { get; set; }
private double Price { get; set; }
private double Change { get; set; }
///...
}
This will allow you to change the state only if the type is StockMarket
like:
class StockMarket
{
public List<Company> Companies { get; set; }
public StockMarket()
{
Companies = new List<Company>();
}
public StockMarket someMethod()
{
//You can change the state here
StockMarket s = new StockMarket();
s.Companies.Add(new Company(this.GetType(), "aa", "_", 123, 1234));
return s;
}
//...
}
Now you cannot change the state here:
public partial class Observer: Form
{
private StockMarket stockMarket;
public ConcreteObserverPull()
{
InitializeComponent();
stockMarket = new StockMarket();
//Here you cannot change the state
stockMarket.Companies.Add(new Company(this.GetType(), "aa", "_", 123,12));
}
//...
}
Sorry, I don't know C#, but as an idea, you can wrap returned entities with decorator or proxy, which will throw an exception in case of trying to modify state of a company.
Returning clones with fields set as readonly is the safest way to go.

Run different code based type

I want to call a method for my WPF-App with subtype objects of my Piece class. My problem is that the subtype objects have more properties than e.g the the Text objects.
Do you know a way to cope with this better than I do in my FillForm example?
namespace Namespace
{
public abstract class Piece
{
public int id { get; set; }
public string title { get; set; }
public string description { get; set; }
}
public class Text : Piece
{
}
public class Image: Piece{
public string filePath { get; set; }
public string fileformat { get; set; }
}
public class Video : Image
{
}
}
}
Example method:
public void FillForm(Piece currentPiece)
{
pieceIdTextBox.Text = currentPiece.id.ToString();
pieceNameTextBox.Text = currentPiece.title;
pieceDescriptionTextBox.Text = currentPiece.description;
if (!currentPiece.GetType().ToString().Equals("Namespace.Text"))
{
pieceFileSelectURLTextBlock.Text = (currentPiece as Namespace.Image).filePath;
SetPreviews((currentPiece as Namespace.Image).filePath);
}
}
Thanks!
Why not just change the method to the following with more type-safety
public void FillForm(Piece currentPiece)
{
pieceIdTextBox.Text = currentPiece.id.ToString();
pieceNameTextBox.Text = currentPiece.title;
pieceDescriptionTextBox.Text = currentPiece.description;
if (currentPiece as Namespace.Image imagePiece)
{
pieceFileSelectURLTextBlock.Text = imagePiece.filePath;
SetPreviews(imagePiece.filePath);
}
}
Do a safecast:
public void FillForm(Piece currentPiece)
{
pieceIdTextBox.Text = currentPiece.id.ToString();
pieceNameTextBox.Text = currentPiece.title;
pieceDescriptionTextBox.Text = currentPiece.description;
var imagePiece = currentPiece as Image;
if(imagePiece != null)
pieceFileSelectURLTextBlock.Text = imagePiece .filePath;
SetPreviews(imagePiece .filePath);
}
}

How do I get DataContractJsonSerializer to use concrete type in type hint when serializing generic class from interface

I have a set of classes as follows: a Command, which Executes and stores a Result;
a Response, which is created as in order to return the Result in a serialized form (plus extra metadata which I've left out). The Response.Result must be of type object, as it is used for a bunch of different commands, each of which can have a Result of any type at all.
The Command is generic, and I'd like it to accept an interface rather than concrete type, but when I do, the serialized response contains the following type hint: "__type":"ResultOfanyType:#serialization"
rather than the following, which is generated when the command accepts a concrete type:
"__type":"ResultOfMyObjectDhOQ6IBI:#serialization"
I need the type hint to contain the concrete type rather than ResultOfanyType. Why are interfaces being treated differently in this context? Notice that when the Type is a direct property of the serialized Command, then the concrete type is contained in the type hint
I've tried changing the the Result's Response property typed to Result, but that has no effect.
Here is the code. Simply uncomment/comment the lines in Main where the command is created and known types listed for the alternative version.
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
namespace serialization
{
class Program
{
static void Main(string[] args)
{
Response response = new Response();
response.ResponseStatus = "ok";
ConcreteCommand command = new ConcreteCommand(); //switch with line below to test inteface
//InterfaceCommand command = new InterfaceCommand();
command.Execute();
response.Results = command.Results;
List<Type> knownTypes = new List<Type>
{
typeof(Result<MyObject>), //switch with Interface lines below to test inteface
typeof(MyObject)
//typeof(Result<IMyObject>),
//typeof(IMyObject)
};
DataContractJsonSerializer serializer = new DataContractJsonSerializer(response.GetType(), knownTypes, int.MaxValue, false, null, true);
Stream stream = new MemoryStream();
serializer.WriteObject(stream, response);
stream.Position = 0;
StreamReader reader = new StreamReader(stream);
string output = reader.ReadToEnd();
Console.WriteLine(output);
}
}
public interface IMyObject
{
string name { get; set; }
}
[DataContract]
[KnownType(typeof(MyObject))]
public class MyObject : IMyObject
{
[DataMember]
public string name { get; set; }
}
[DataContract]
public class Result<T>
{
[DataMember]
public string Status { get; set; }
[DataMember]
public T Item { get; set; }
}
public abstract class BaseCommand<T>
{
protected Result<T> results = new Result<T>();
protected T resultObject;
public object Results
{
get { return this.results; }
}
public T ResultObject
{
get { return this.resultObject; }
}
public abstract void Execute();
}
public class InterfaceCommand : BaseCommand<IMyObject>
{
public override void Execute()
{
IMyObject myobject = new MyObject();
myobject.name = "my object";
Result<IMyObject> result = new Result<IMyObject>();
result.Item = myobject;
result.Status = "ok";
this.results= result;
this.resultObject = myobject;
}
}
public class ConcreteCommand : BaseCommand<MyObject>
{
public override void Execute()
{
MyObject myobject = new MyObject();
myobject.name = "my object";
Result<MyObject> result = new Result<MyObject>();
result.Item = myobject;
result.Status = "ok";
this.results = result;
this.resultObject = myobject;
}
}
[DataContract]
public class Response
{
[DataMember]
public string ResponseStatus { get; set; }
[DataMember]
public object Results { get; set; }
}
}
Let's start with this question and that might explain everything.
I need the type hint to contain the concrete type rather than ResultOfanyType. Why are interfaces being treated differently in this context?
An interface is basically just a contract for what a class implementing it should contain and multiple classes could implement its members. For example.
public interface IPerson
{
int Id { get; set; }
string FirstName { get; set; }
string LastName { get; set; }
}
public class Person : IPerson
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
}
public class Contact : IPerson
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Company { get; set; }
public string PhoneNumber { get; set; }
}
So when you call an IPerson what are you expecting back? A Person or a Contact? Each has an id and the basic components of a name, but each also has unique properties that IPerson doesn't even know exist. This is why when you try to get an interface to resolve to a concrete class, you're not going to get anywhere without some sort of factory class to figure out what you want. So in this case, if I wanted to resolve an IPerson, I'd add the following line of code...
var objectType = iPersonObject.GetType();
In your case, you'd want to try calling GetType() on result.Item. This tells .NET to look at the actual type of the object implementing the interface and return it.
How about this...
class Program
{
static void Main(string[] args)
{
Response response = new Response();
response.ResponseStatus = "ok";
//ConcreteCommand command = new ConcreteCommand(); //switch with line below to test inteface
InterfaceCommand command = new InterfaceCommand();
command.Execute();
response.Results = command.Results;
List<Type> knownTypes = new List<Type>
{
typeof(MyObject),
typeof(Result<MyObject>) //switch with line below to test inteface
//typeof(Result<IMyObject>)
};
DataContractJsonSerializer serializer = new DataContractJsonSerializer(response.GetType(), knownTypes, int.MaxValue, false, null, true);
Stream stream = new MemoryStream();
serializer.WriteObject(stream, response);
stream.Position = 0;
StreamReader reader = new StreamReader(stream);
string output = reader.ReadToEnd();
Console.WriteLine(output);
}
}
public interface IMyObject
{
string name { get; set; }
}
[DataContract]
public class MyObject : IMyObject
{
[DataMember]
public string name { get; set; }
}
[DataContract]
public class Result<T>
{
[DataMember]
public string Status { get; set; }
[DataMember]
public T Item { get; set; }
}
public abstract class BaseCommand
{
protected Result<IMyObject> results = new Result<IMyObject>();
public Result<IMyObject> Results
{
get { return this.results; }
}
public abstract void Execute();
}
public class InterfaceCommand : BaseCommand
{
public override void Execute()
{
IMyObject myobject = new MyObject();
myobject.name = "my object";
Result<IMyObject> result = new Result<IMyObject>();
result.Item = myobject;
result.Status = "ok";
this.results= result;
}
}
public class ConcreteCommand : BaseCommand
{
public override void Execute()
{
MyObject myobject = new MyObject();
myobject.name = "my object";
Result<IMyObject> result = new Result<IMyObject>();
result.Item = myobject;
result.Status = "ok";
this.results = result;
}
}
[DataContract]
public class Response
{
[DataMember]
public string ResponseStatus { get; set; }
[DataMember]
public Result<IMyObject> Results { get; set; }
}
Outputs...
{"__type":"Response:#ConsoleApplication2","ResponseStatus":"ok","Results":{"__ty
pe":"ResultOfanyType:#ConsoleApplication2","Item":{"__type":"MyObject:#ConsoleAp
plication2","name":"my object"},"Status":"ok"}}
If you're trying to make some sort of generic contract, you're going to have to have some sort of common base class/interface. It won't work with object but you can go ala COM and make your own IUnknown interface from which to create as many subclasses as you like, as long as they are included within your known types.

Categories

Resources