public class RegistrationManager
{
public List<object> RegisteredObjects;
public bool TryRegisterObject(object o)
{
// ...
// Add or not to Registered
// ...
}
}
I want that RegisterObjects be accessible from outside of the class, but also that the only way to populate the RegisterObjects list is through TryRegisterObject(object o).
Is this possible ?
I would hide it under ReadonlyCollection. In this case client won't be able to add elements via casting to IList for example. It totaly depends on how secure you want to be (in simplest scenario exposing IEnumerable will be pretty enough).
public class RegistrationManager
{
private List<object> _registeredObjects;
ReadOnlyCollection<object> _readOnlyRegisteredObjects;
public RegistrationManager()
{
_registeredObjects=new List<object>();
_readOnlyRegisteredObjects=new ReadOnlyCollection<object>(_registeredObjects);
}
public IEnumerable<object> RegisteredObjects
{
get { return _readOnlyRegisteredObjects; }
}
public bool TryRegisterObject(object o)
{
// ...
// Add or not to Registered
// ...
}
}
Hide it under IEnumerable. You'll get "readonly" collection outise the class and work with List inside:
public class RegistrationManager
{
public IEnumerable<object> RegisteredObjects
{
get
{
return _registeredObjects;
}
}
private List<object> _registeredObjects;
public bool TryRegisterObject(object o)
{
// ...
// Add or not to Registered
// ...
}
}
More protected variant with IReadOnlyColection:
public class RegistrationManager
{
public IReadOnlyCollection<object> RegisteredObjects
{
get { return new ReadOnlyCollection<object>(_registeredObjects); }
}
private List<object> _registeredObjects;
public bool TryRegisterObject(object o)
{
// ...
// Add or not to Registered
// ...
}
}
Something like that (I guess you have to have read-only access which means that Add, RemoveAt, Clear etc. are not allowed):
public class RegistrationManager
{
// change RegisteredObjects to be private
//TODO: do you really want List<object> instead of, say, List<RegisteredItem>?
private List<object> RegisteredObjects = new List<object>();
// let RegisteredObjects be visible as read-only
public IReadOnlyList<object> Items {
get {
return RegisteredObjects;
}
}
// your TryRegisterObject
public bool TryRegisterObject(object o)
{
// ...
// Add or not to Registered
// ...
}
}
downside of the solution is that, technically, it's possible to cast back, e.g.
RegistrationManager manager = ...
// you can't do this
// manager.Items.Add(new Object()); // <- compile time error
// but can do this
((List<Object>) (manager.Items)).Add(new Object());
return it as IReadOnlyList
public class RegistrationManager
{
private List<object> _registeredObjects;
public IReadOnlyList<object> RegisteredObjects
{
get{ return _registeredObjects; }
}
public bool TryRegisterObject(object o)
{
// ...
// Add or not to Registered
// ...
}
}
Yes you can expose a property of type IReadOnlyCollection(T).
List(T) implements IReadonlyCollection(T)
public class RegistrationManager
{
private List<object> _registeredObjects;
public IReadOnlyCollection<object> RegisteredObjects
{
get
{
return _registeredObjects as IReadOnlyCollection<object>;
}
}
}
Related
I need to validate an item added to a list in C#. I've looked at this article: Validating lists in C#, but it isn't working.
returnModel.FileSystemItems.Add(new FileManagerFileSystemItem
{
Name = item.FolderName,
Key = item.FolderId.ToString(),
Key2 = "folder",
Key3 = key3,
IsDirectory = true,
HasSubDirectories = list.Any(a => a.ParentId == item.FolderId),
DateModified = DateTime.Now,
Size = 0,
Metadata = metadata,
Permissions = key3 == FileManagerFolderType.Private.ToString() ? GetPrivateFolderPermissions() : GetPublicFolderPermissions(hasFileManager)
});
So I want to make sure they set Key to an id or make sure Key2 is set to "Files" or "Folders"
I'm not trying to validate really the end-user, but validate to make sure the developer has set all the necessary properties when using the list.
Of course, I could add a Validate() method within the class to validate it after they are done adding to it, but then the developer would have to know to add that code at the end, which kind of defeats the purpose.
I tried to do the example here: https://stackoverflow.com/a/51523347/13698253, but it will never hit the breakpoint in the code.
Any ideas on how to solve this OR do I just need to add my own validation method at the end of the list that will make sure that the developer added everything properly.
This is not in a model validation for the model state of the controller. This is just in a normal class that might not be tied to MVC etc.
Thanks.
You can create your own custom List class which will throw an exception if the item being added is invalid:
public FileManagerFileSystemItemList : List<FileManagerFileSystemItem>
{
// edit: added TryAdd as per other's suggestions
// all this does is wrap the Add call in a try/catch block
// which would be enough to prevent unwanted exceptions
// but using Add alone would throw potentially useful exceptions
// for the developer to then deal with.
public bool TryAdd(FileManagerFileSystemItem item)
{
try
{
Add(item);
return true;
}
catch
{
return false;
}
}
new public void Add(FileManagerFileSystemItem item)
{
Validate(item);
base.Add(item);
}
private void Validate(FileManagerFileSystemItem item)
{
if (!Guid.TryParse(item.Key, out _))
throw new Exception("Key is not an id");
// ... and other validation
}
}
If however you wanted something more generic, you could put the validation into the class to be validated and have it implement an interface that can then be used as a constraint in a ValidatableList:
public interface IValidatable
{
bool IsValid { get; }
void Validate();
}
public class ValidatableList<T> : List<T> where T : class, IValidatable
{
public bool TryAdd(T item)
{
if (!item.IsValid)
return false;
base.Add(item);
return true;
}
new public void void Add(T item)
{
item.Validate();
base.Add(item);
}
}
public class FileManagerFileSystemItem : IValidatable
{
...
// rest of your class
...
public bool IsValid
{
get
{
try
{
Validate();
return true;
}
catch
{
return false;
}
}
}
public void Validate()
{
if (!Guid.TryParse(Key, out _))
throw new Exception("Key is not an id");
// ... and other validation
}
}
// Now your FileSystemItems property would be an instance of the new List class
...
ValidatableList<FileManagerFileSystemItem> FileSystemItems ...
...
The only potential issue I can see with the above is if the class you want a list of is not one you can modify to add in your validation. In this case you would need a separate validator class that handles this for your object which would look more like:
public interface IValidator<T> where T : class
{
bool IsValid(T item);
void Validate(T item);
}
public class FileSystemItemValidator : IValidator<FileManagerFileSystemItem>
{
public bool IsValid(T item)
{
try
{
Validate(item);
return true;
}
catch
{
return false;
}
}
public void Validate(T item)
{
if (!Guid.TryParse(item.Key, out _))
throw new Exception("Key is not an id");
// ... and other validation
}
}
// and the list class needs to know which class can validate its items
public class ValidatableList<T, TValidator> : List<T> where TValidator : class, IValidator<T>, new()
{
private readonly TValidator _validator;
public ValidatableList()
: base()
{
_validator = new TValidator();
}
public bool TryAdd(T item)
{
if (!_validator.IsValid(item))
return false;
base.Add(item);
return true;
}
new public void void Add(T item)
{
_validator.Validate(item);
base.Add(item);
}
}
// Now your FileSystemItems property would be an instance of the new List class
...
ValidatableList<FileManagerFileSystemItem, FileSystemItemValidator> FileSystemItems ...
...
I have some device classes like the following sample:
public class MoveSensor() {
public uint GetData() {
// Some logic here
}
}
public class TemperatureSensor {
public double GetData() {
// Some logic here
}
}
public class MultiSensorUnit() {
public MultiSensorData GetData() {
// Some logic here
}
}
public class MultiSensorData {
public int SomeSensor1Data { get; set; }
public byte SomeSensor2Data { get; set; }
public double SomeSensor3Data { get; set; }
}
Yet I have a class to periodically collect a data from these devices:
public class DataCollector() {
public void CollectData() {
// Here I want to collect a data from all devices
}
}
Looks like I should use an interface:
public interface IDataRecievable {
[This is a problem place] GetData();
}
But I can't do it because GetData() returns different types from different devices. I need a design pattern to make usage of devices in DataCollector more universal and generic.
With all of your sensors returning different kinds of data, you may consider move your data processing into each sensor implementation.
If you can do that, here is how I would implement it.
Declare an interface
public interface IDataRecievable<T>
{
T GetData();
void CollectData();
}
And concrete classes:
public class MoveSensor : IDataRecievable<uint>
{
public void CollectData()
{
//do collect logic here
}
public uint GetData()
{
//do get data
}
}
public class TemperatureSensor : IDataRecievable<double>
{
public void CollectData()
{
//do collect logic here
}
public double GetData()
{
//do get data
}
}
And data collector class
public class DataCollector
{
public void CollectData()
{
var typesToRegister = Assembly.GetExecutingAssembly().GetTypes()
.Where(type => !String.IsNullOrEmpty(type.Namespace))
.Where(type => type.GetInterfaces().Any(x => x.IsGenericType
&& x.GetGenericTypeDefinition() == typeof(IDataRecievable<>)));
foreach (var type in typesToRegister)
{
dynamic sensor = Activator.CreateInstance(type);
sensor.CollectData();
}
}
}
I get all classes implement IDataRecievable<>, create an instance and call the CollectData() method. You can always call GetData() isstead of CollectData() if you want.
You could encapsulate the functionality of the returned data into various implementations of the same interface. For example, if the data will be displayed, each sensor returns a different type that displays the data in a different way. For example:
public interface Sensor {
Data GetData();
}
public interface Data {
void Display();
}
public class IntData : Data {
public void Display() { ... }
}
public class DoubleData : Data {
public void Display() { ... }
}
public class MoveSensor : Sensor {
public IntData GetData() {
// ... return IntData ...
}
}
public class TemperatureSensor : Sensor {
public DoubleData GetData() {
// ... return DoubleData ...
}
}
Then some client can iterate through each sensor and display the data:
List<Sensor> sensors = // ...
foreach (Sensor sensor in sensors) {
sensor.Display();
}
This is not restricted to displaying the data, the Data interface can incorporate any type of functionality. For example, if the data needed to be stored into a database, you can pass some proxy to the database to a method and each Data implementation would know how to store itself in the database:
public class DatabaseProxy {
public void StoreInt(int value) { ... }
public void StoreDouble(double value) { ... }
}
public interface Data {
void StoreData(DatabaseProxy proxy);
}
public class IntData : Data {
private int _value;
public IntData(int value) {
_value = value;
}
public void StoreData(DatabaseProxy proxy) {
proxy.StoreInt(_value);
}
}
public class DoubleData : Data {
private double _value;
public DoubleData(double value) {
_value = value;
}
public void StoreData(DatabaseProxy proxy) {
proxy.StoreDouble(_value);
}
}
The idea is to shift the responsibility of using the returned data away from some external entity and hand it to the data itself. Ergo, the Data implementation is closest to the data it is storing and thus, it should be responsible for handling it. If there are too many things that need to be accomplished by Data, then more complex techniques can be used, like handlers or callbacks to separate the data from the handling of data.
It depends on what the results of each sensor are going to be. You have given examples of a uint and a double. I guess other sensors could in theory return strings or even complex compound objects.
The answer from a sensor is meaningless without knowledge of what that sensor measures, and that would obviously be known to the consumer of this data. Is your problem in the intermediate storage in DataCollector?
I can imagine Dictionary where you would want to hold an arbitrary number of sensors and their results. Can you live with the boxing/unboxing performance overheads? If there isn't a massive number of sensors then this should be negligible. If so, you can do something like:
using System;
using System.Collections.Generic;
using System.Linq;
public interface IDataRecievable
{
object GetData();
}
public class PiSensor : IDataRecievable
{
public object GetData() {
return (object)3.14m;
}
}
public class StringSensor : IDataRecievable
{
public object GetData() {
return (object)"Hello World";
}
}
public class DataCollector
{
private List<IDataRecievable> sensors;
private Dictionary<Type, object> sensorResults = new Dictionary<Type, object>();
public DataCollector(IEnumerable<IDataRecievable> sensorsToPoll)
{
this.sensors = sensorsToPoll.ToList();
}
public T GetResultFromSensor<T>(Type sensorType)
{
return (T)this.sensorResults[sensorType];
}
public void CollectData()
{
foreach (IDataRecievable sensor in this.sensors)
{
sensorResults[sensor.GetType()] = sensor.GetData();
}
}
}
public class Program
{
public static void Main()
{
List<IDataRecievable> sensors = new List<IDataRecievable>
{
new PiSensor(),
new StringSensor()
};
DataCollector dc = new DataCollector(sensors);
dc.CollectData();
decimal pi = dc.GetResultFromSensor<decimal>(typeof(PiSensor));
string greeting = dc.GetResultFromSensor<string>(typeof(StringSensor));
Console.WriteLine(2 * pi);
Console.WriteLine(greeting);
}
}
I would also probably go with Trung Le's implementation, but I would also have some interface for giving the result of the collecion:
public interface ICollectResultReceiver
{
void ReceiveCollectResult(
// whatever you are storing
object someData
);
}
I would also use another interface for the collection process, because it feels like data collection isn't a part of getting data:
public interface IDataRecievable<T>
{
T GetData();
}
public interface IDataCollectable
{
void CollectData(ICollectDataResultReceiver resultReceiver);
}
This way the user of IDataCollectable classes don't need to care about the types, and just use a for loop to run all the collection.
public interface IDataCollector
{
void Add(IDataCollectable collectable);
void CollectData();
}
public class DataCollector : IDataCollector
{
private readonly ICollectDataResultReceiver _resultReceiver;
private readonly List<IDataCollectable> _collectables = new List<IDataCollectable>();
public DataCollector(ICollectDataResultReceiver resultReceiver)
{
_resultReceiver = resultReceiver;
}
public void Add(IDataCollectable collectable)
{
_collectables.Add(collectable);
}
public void CollectData()
{
foreach(var collectable in _collectables)
{
collectable.CollectData(_resultReceiver);
}
}
}
Other than that, I would also make interfaces for each sensor, because there are times where knowing what kind of module you're using is necessary.
public interface IMoveSensorDataReceivable : IDataReceivable<uint> { }
public interface ITemperatureSensorDataReceivable : IDataReceivable<double> { }
public interface IMultiSensorDataReceivable : IDataReceivable<MultiSensorData> { }
So MultiSensorData would be more visible of what kind of data it has.
public class MultiSensorData
{
public uint GetSensorData1() => _moveSensor.GetData();
public double GetSensorData2() => _temperatureSensor.GetData();
private readonly IMoveSensorDataReceivable _moveSensor;
private readonly ITemperatureSensorDataReceivable _temperatureSensor;
public MultiSensorData(
IMoveSensorDataReceivable moveSensor,
ITemperatureSensorDataReceivable temperatureSensor)
{
_moveSensor = moveSensor;
_temperatureSensor = temperatureSensor;
}
}
It is also important to use interfaces instead of concrete classes for better testing. Even though MultiSensorData doesn't need much testing, your tests would be like so:
public class TestClass
{
[Fact]
public void MultiSensorDataTest()
{
var dummyTempSensor = new DummyTempSensor();
var dummyMoveSensor = new DummyMoveSensor();
var multiSensorData = new MultiSensorData(dummyMoveSensor, dummyTempSensor);
Assert.Equal(10, multiSensorData.GetSensorData1());
Assert.Equal(0.5, multiSensorData.GetSensorData2());
}
private class DummyTempSensor : ITemperatureSensorDataReceivable
{
public double GetData() => 0.5;
}
private class DummyMoveSensor : IMoveSensorDataReceivable
{
public uint GetData() => 10;
}
}
I have something like this:
class BaseArg { }
class DerivedArg : BaseArg { }
interface IDoSomething
{
void DoSomething();
}
class A : IDoSomething
{
public BaseArg Value { get; set; }
public A(BaseArg value)
{
this.Value = value;
}
public static A Create(BaseArg arg)
{
return new A(arg);
}
public static B Create(DerivedArg arg)
{
return new B(arg);
}
public virtual void DoSomething()
{
}
}
class B : A
{
public DerivedArg DerivedValue { get; set; }
public B(DerivedArg value)
: base(value)
{
this.DerivedValue = value;
}
public override void DoSomething()
{
// does something different from A.DoSomething()
// uses additional stuff in DerivedArg
}
}
However, even when I do this:
DerivedArg arg = new DerivedArg();
A a = A.Create(arg);
A.Create(BaseArg arg) is called (and thus A is created, which was not the intention).
Am I missing something here? If so, how should I rewrite this without using weird stuff such as conditions on arg as DerivedArg.
The correct factory method is getting executed. Set a breakpoint inside of:
public static B Create(DerivedArg arg)
{
return new B(arg); /* set breakpoint */
}
It appears to you that it isn't being executed since you've defined the local variable of type A:
A a = A.Create(arg);
public static B Create(DerivedArg arg) is being called properly and an instance of type B is being returned and boxed as type A.
I need to refactor the following class:
public interface IEmployee
{
int VacationWeeks { get; }
int YearsWithCompany { set; get; }
double Salary { set; get; }
}
public class Employee : IEmployee
{
private readonly int vacationWeeks;
public Employee(int vacationWeeks)
{
this.vacationWeeks = vacationWeeks;
}
public int VacationWeeks
{
get { return vacationWeeks; }
}
public int YearsWithCompany { set; get; }
public double Salary { set; get; }
}
I need to make sure that VacationWeeks depends only on YearsWithCompany, and I am loading the mapping from the database. So far I have come up with this:
public class EmployeeNew : IEmployee
{
private Dictionary<int,int> vacationWeeksTable;
public EmployeeNew(Dictionary<int, int> vacationWeeksTable)
{
this.vacationWeeksTable = vacationWeeksTable;
}
public int VacationWeeks
{
get { return vacationWeeksTable[YearsWithCompany]; }
}
public int YearsWithCompany { set; get; }
public double Salary { set; get; }
}
This class implements what I want, but it still has one vulnerability: different instances of EmployeeNew in the same collection may have been created with different instances of vacationWeeksTable.
All instances of EmployeeNew in the same collection must refer to the same vacationWeeksTable.
The application I am refactoring uses lots of List all over the system, and we need to be able to modify YearsWithCompany and Salary, yet to guarantee that only one vacationWeeksTable is used per List. These lists are iterated several times; its elements are modified in each iteration.
Here is my imperfect solution. Suggestions are welcome:
// this class does two things, which I do not like
public class EmployeeList : IEnumerable<IEmployee>, IEmployee
{
private Dictionary<int, int> vacationWeeksTable;
private List<EmployeeSpecificData> employees;
private int currentIndex;
private EmployeeSpecificData CurrentEmployee
{
get { return employees[currentIndex]; }
}
public IEnumerator<IEmployee> GetEnumerator()
{
for (currentIndex = 0; currentIndex < employees.Count; currentIndex++)
{
yield return this;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public int VacationWeeks
{
get { return vacationWeeksTable[YearsWithCompany]; }
}
// this is ugly repetitive code I don't like
public int YearsWithCompany
{
get { return CurrentEmployee.YearsWithCompany; }
set { CurrentEmployee.YearsWithCompany = value; }
}
// this is ugly repetitive code I don't like
public double Salary
{
get { return CurrentEmployee.Salary; }
set { CurrentEmployee.Salary = value; }
}
}
I use the following to create and init some of the classes that need default and shared behaviour. Maybe if you can refactor it will help:
It is some form of the Factory and FlyWeight patterns combined (the flyweight part can be removed in your scenario), which in addition has a concept of class Type shared handlers.
I simplified and removed some stuff that you wont need but there is more to remove, I added comments.
Usage would be: (app init)
Dictionary<int,int> vacationWeeksTable = new Dictionary<int,int>();
// fill the table
Factory<Employee>.Init(vacationWeeksTable);
The whenever you create a Employee class:
// remove grouping in the factory class to remove this null
Employee em = Factory<Employee>.Create(null);
It takes only a WeakReference to the classes so you don't have to worry about GC.
Each employee will have the shared vacationWeeksTable setup on creation, without the possibility to change it after from outside if not using the factory class.
You could change the vacation table for all running instances of Employee at any moment in the runtime of the app with:
// this will call the method registered for SetInitialdata on all instances of Employee classes.
// again remove grouping to remove that null
Factory<Employee>.Call(EventHandlerTypes.SetInitialData, null, vacTable);
Sample implementation of Employee:
class Employee : IBaseClass
{
private Dictionary<int, int> vacationWeeksTable;
public virtual void RegisterSharedHandlers(int? group, Action<IKey, int?, EventHandlerTypes, Action<object, SharedEventArgs>> register)
{
group = 0; // disable different groups
register(new Key<Employee, int>(0), group, EventHandlerTypes.SetInitialData, SetVacationWeeksTable);
}
public virtual void RegisterSharedData(Action<IKey, object> regData)
{
// remove this from factory and interface, you probably dont need it
// I have been using it as a FlyWeight data store for classes.
}
private void SetVacationWeeksTable(object sender, SharedEventArgs e)
{
vacationWeeksTable = e.GetData<Dictionary<int, int>>();
}
}
Code pattern Implementation:
IBaseClass : interface that each of my classes that are creatable through a factory implement
public enum EventHandlerTypes
{
SetInitialData // you can add additional shared handlers here and Factory<C>.Call - it.
}
public class SharedEventArgs : EventArgs
{
private object data;
public SharedEventArgs(object data)
{
this.data = data;
}
public T GetData<T>()
{
return (T)data;
}
}
public interface IBaseClass
{
void RegisterSharedHandlers(int? group, Action<IKey, int?, EventHandlerTypes, Action<object, SharedEventArgs>> regEvent);
void RegisterSharedData(Action<IKey, object> regData);
}
Utility generic classes:
public interface IKey
{
Type GetKeyType();
V GetValue<V>();
}
public class Key<T, V> : IKey
{
public V ID { get; set; }
public Key(V id)
{
ID = id;
}
public Type GetKeyType()
{
return typeof(T);
}
public Tp GetValue<Tp>()
{
return (Tp)(object)ID;
}
}
public class Triple<T, V, Z>
{
public T First { get; set; }
public V Second { get; set; }
public Z Third { get; set; }
public Triple(T first, V second, Z third)
{
First = first;
Second = second;
Third = third;
}
}
Factory class with slight modification to handle your scenario:
public static class Factory<C> where C : IBaseClass, new()
{
private static object initialData;
private static Dictionary<IKey, Triple<EventHandlerTypes, int, WeakReference>> handlers = new Dictionary<IKey, Triple<EventHandlerTypes, int, WeakReference>>();
private static Dictionary<IKey, object> data = new Dictionary<IKey, object>();
static Factory()
{
C newClass = new C();
newClass.RegisterSharedData(registerSharedData);
}
public static void Init<IT>(IT initData)
{
initialData = initData;
}
public static Dt[] GetData<Dt>()
{
var dataList = from d in data where d.Key.GetKeyType() == typeof(Dt) select d.Value;
return dataList.Cast<Dt>().ToArray();
}
private static void registerSharedData(IKey key, object value)
{
data.Add(key, value);
}
public static C Create(int? group)
{
C newClass = new C();
newClass.RegisterSharedHandlers(group, registerSharedHandlers);
// this is a bit bad here since it will call it on all instances
// it would be better if you can call this from outside after creating all the classes
Factory<C>.Call(EventHandlerTypes.SetInitialData, null, initialData);
return newClass;
}
private static void registerSharedHandlers(IKey subscriber, int? group, EventHandlerTypes type, Action<object, SharedEventArgs> handler)
{
handlers.Add(subscriber, new Triple<EventHandlerTypes, int, WeakReference>(type, group ?? -1, new WeakReference(handler)));
}
public static void Call<N>(EventHandlerTypes type, int? group, N data)
{
Call<N>(null, type, group, data);
}
public static void Call<N>(object sender, EventHandlerTypes type, int? group, N data)
{
lock (handlers)
{
var invalid = from h in handlers where h.Value.Third.Target == null select h.Key;
// delete expired references
foreach (var inv in invalid.ToList()) handlers.Remove(inv);
var events = from h in handlers where h.Value.First == type && (!#group.HasValue || h.Value.Second == (int)#group) select h.Value.Third;
foreach (var ev in events.ToList())
{
// call the handler
((Action<object, SharedEventArgs>)ev.Target)(sender, arg);
}
}
}
}
Make a class which contains a Dictionary. Creating or getting instance of this new class will load the dictionary in a consistent way. Then your BOs can take an instance of the class, thus ensuring they're all using the same data (because the class containingthe list knows how to load itself with the proper set of data).
I'm creating a table from a dynamically created IBindingList using
class TableBuilder
{
private Type m_TableType;
// ... create and define m_TableType here
public IBindingList CreateTable()
{
return Activator.CreateInstance(m_TableType) as IBindingList;
}
}
class DynamicTable : IBindingList
{
private IBindingList m_theList;
private TableBuilder m_tableBuilder;
public DynamicTable(TableBuilder tableBuilder)
{
m_tableBuilder = tableBuilder;
m_theList = tableBuilder.CreateTable();
}
public void LoadData()
{
// ...
}
}
I would like to promote the IBindingList functionality of m_theList to the level of the class so I can make calls like
var myTable = new DynamicTable(someTableBuilder);
int count = myTable.Count;
myTable.LoadData();
count = myTable.Count;
How can I get all the m_theList public members to be members of DynamicTable. I can not derive DynamicTable from m_TableType since it is only known at run time.
-Max
You will have to do it as old subclassing, implement the interface and in each method call the corresponding method in m_theList:
//methods
public void AddIndex(PropertyDescriptor property)
{
m_theList.AddIndex(property);
}
public object AddNew()
{
return m_theList.AddNew();
}
//properties
public bool AllowEdit
{
get { return m_theList.AllowEdit; }
}
....
//for events you can use add/remove syntax
public event ListChangedEventHandler ListChanged
{
add { m_theList.ListChanged += value; }
remove { m_theList.ListChanged -= value; }
}
....
//indexer...
public object this[int index]
{
get
{
return m_theList[index];
}
set
{
m_theList[index] = value;
}
}