I'd like to have two simple calls in a class that would be transformed by other classes. Something like:
ObjectCreator.CreateBlank<Human>();
ObjectCreator.CreatePopulated<Human>();
ObjectCreator.CreateBlank<Dog>();
ObjectCreator.CreatePopulated<Dog>();
I currently do this:
public class ObjectCreator
{
public static T CreateBlank<T>()
{
return Activator.CreateInstance<T>();
}
public static T CreatePopulated<T>()
{
//Somehow return new object with populated properties
}
}
I am struggling with the populated part. I'd like it to return a "default" object of that type with defined properties. I've tried a few things involving passing in interfaces, but it gets messy fast (I don't expect this to be particularly clean either)
So If I called ObjectCreator.CreatePopulated(), I'd like it to somehow go to a different class where I create a new Anything, and fill it's properties to specific values. It feels like I'm close but missing a piece of the puzzle here.
My end game here is to have the call be as simple / readable as possible.
Any help is appreciated.
I DO realize it'd probably be easier to simply call a class that creates and populates each object, but this is a learning exercise for me and I'd like to attempt to get this working as generically as possible.
I would recommend doing something like this:
public interface IPopulatable
{
void Populate();
}
public class ObjectCreator
{
public static T CreateBlank<T>() where T : new ()
{
return new T();
}
public static T CreatePopulated<T>() where T : IPopulatable, new()
{
var populatable = new T();
populatable.Populate();
return populatable;
}
}
public class Human : IPopulatable
{
public string Name { get; set; }
public void Populate()
{
Name = "Joe";
}
}
Related
I've made a class with T. It looks like this.
public interface ISendLogic<T> where T : NarcoticsResult
{
ChangeType Change_New();
ChangeType Change_Cancel();
PurchaseType Purchase_New();
PurchaseType Purchase_Cancel();
}
public class SendLogic<T> : ISendLogic<T> where T : NarcoticsResult
{
private eReportType _type;
private bool Send_Change()
{
// Send to server by xml file
}
private bool Send_Purchase()
{
// Send to server by xml file
}
public ChangeType Change_New()
{
_type = change_new;
Send_Change();
}
public ChangeType Change_Cancel()
{
_type = change_cancel;
Send_Change();
}
public PurchaseType Purchase_New()
{
_type = purchase_new;
Send_Purchase();
}
public PurchaseType Purchase_Cancel()
{
_type = purchase_cancel;
Send_Purchase();
}
}
There are two types, ChangeType and PurchaseType
and these are inherited from NarcoticsResult.
I thought the person who want to use this class would use it like this.
// this class can only be used when someone wants to use change function
var logic = SendLogic<ChangeType >();
logic.Change_New();
logic.Change_Cancel();
Here is a question.
I want to force this class to be used only as I thought.
I mean, I want to prevent it to be used like this.
var logic = SendLogic<ChangeType>();
logic.Change_New(); // OK
logic.Purchase_New(); // You should make this class like SendLogic<PurchaseType>()
I thought I add some code which check type of T in every function.
How do you think the way I thought. I think there are better way to fix it
Please tell me a better way
thank you.
Personally, I don't think you need a generic class in this case. What you need is either an abstract base class or an interface. I personally love the interface approach as below:
public interface ISendLogic {
void New();
void Cancel();
}
So now you've got a contract that will force the consumer of your code to use New or Cancel methods only.
The next step you can implement that send logic interface for your specific implementation:
public class ChangeSendLogic : ISendLogic {
private eReportType _type;
public ChangeSendLogic(
/*you can put the necessary parameters in the constructor
and keep it as private fields in the object*/
)
{
}
private bool Send_Change()
{
// Send to server by xml file
}
public void New()
{
_type = change_new;
Send_Change();
}
public void Cancel()
{
_type = change_cancel;
Send_Change();
}
}
public class PurchaseSendLogic : ISendLogic {
private eReportType _type;
public PurchaseSendLogic(
/*you can put the necessary parameters in the constructor
and keep it as private fields in the object*/
)
{
}
private bool Send_Purchase()
{
// Send to server by xml file
}
public void New()
{
_type = change_new;
Send_Purchase();
}
public void Cancel()
{
_type = change_cancel;
Send_Purchase();
}
}
From here you can see those two classes handle the implementation for each type nicely. You can think this is as an implementation of single responsibility principle. So if you have one more type, you can just add one more implementation of this interface rather than updating the existing classes.
If you want to hide the creation of those objects, in the next part you can introduce a kind of factory or selector as below:
public enum SendLogicType {
Change,
Purchase
}
public static SendLogicSelector {
public static ISendLogic GetSendLogic(SendLogicType type)
{
switch(type)
{
case SendLogicType.Change:
return new ChangeSendLogic();
case SendLogicType.Purchase:
return new PurchaseSendLogic();
}
}
}
This is how the code will be consumed:
ISendLogic sendLogic = SendLogicSelector.GetSendLogic(SendLogicType.Change);
sendLogic.New(); // change new logic executed
sendLogic.Cancel(); // change cancel logic executed
sendLogic = SendLogicSelector.GetSendLogic(SendLogicType.Purchase);
sendLogic.New(); // purchase new logic executed
sendLogic.Cancel(); // purchase cancel logic executed
Hopefully, you can get the idea of my approach. Good luck! :)
Thank you for your comment
I divided it into two parts like below
public class ChangeSendLogic : SendLogic<ChangeType>, IChangeLogic
public class PurchaseSendLogic : SendLogic<PurchaseType>, IPurchaseLogic
And I also divided interface too
public interface IChangeLogic
{
ChangeType Change_New();
ChangeType Change_Cancel();
}
public interface IPurchaseLogic
{
PurchaseType Purchase_New();
PurchaseType Purchase_Cancel();
}
And I made SendLogic<T> class to abstract class.
This is because I want to make the person who wants to use this class to use a class that inherits from this class without directly accessing it.
Thank you for your comment. I got a good idea.
I have a class for my acquisition device. Then I want to create another class that generates random samples for when my acquisition device is not connected.
This is my object:
private object AmplifierObj;
And I want a create it like that
if (AmpSettingsObj.DaqDevice == "noAmp")
AmpObj = new NoAmpManager(sampleRate: sampleRate);
else
AmpObj = new USBampManager(optCalibrationFlag: calibrationFlag,
serialNumbers: serialNumbers, sampleRate: sampleRate);
However, when I call one of the methods I get the error "object" does not contain a definition for the method . Both classes have exactly the same methods implemented. What would be the best way of implementing it? Should I use a generic class as a placeholder?
If both classes have the same methods you should have an interface (IAmplifier) and both classes should implement this interface.
This can be easily done by right clicking one of the classes and selecting Refactor / Extract Interface.
Assuming your interface name is IAmplifier, have both classes implement the same interface such as:
public class NoAmpManager : IAmplifier
{
... (Methods)
... (Properties)
}
public class USBampManager : IAmplifier
{
... (Methods)
... (Properties)
}
Then, instead of
private object AmplifierObj;
Use
private IAmplifier AmplifierObj;
You can do it like this
public class AmplifierObj
{
public Object AnySameProperty { get; set; }
}
public class NoAmpManager: AmplifierObj
{
public void Foo()
{
}
}
public class USBampManager : AmplifierObj
{
public void Bar()
{
}
}
But always must call the sub class property you should check object type
AmplifierObj AmpObj;
if (AmpSettingsObj.DaqDevice == "noAmp")
AmpObj = new NoAmpManager(sampleRate: sampleRate);
else
AmpObj = new USBampManager(optCalibrationFlag: calibrationFlag,
serialNumbers: serialNumbers, sampleRate: sampleRate);
if (AmpObj.GetType() == typeof(NoAmpManager))
((NoAmpManager)AmpObj).Foo();
else
((USBampManager)AmpObj).Bar();
In the C# code listed below, I get a "NullReferenceException" with the error:
"Object reference not set to an instance of an object"
I guess the error is related to the inheritance and/or the template definitions. The list gets initialized, and when debugging I can confirm that the list does not point to NULL. I can't figure out how to do this in another way. (Sorry about the confusing class names / structure). The exception happens here: this.localSMT.doSomething(base.list);
public class VTEST<V>
{
public List<V> list;
public LocalSMT<V> localSMT;
public VTEST()
{
list = new List<V>();
}
}
public class VTEST_FSUB<V> : VTEST<V>
{
public VTEST_FSUB()
{
do_virtual();
}
public void do_virtual()
{
this.localSMT.doSomething(base.list);
}
}
public class VTEST_RUN : VTEST_FSUB<int>
{
public VTEST_RUN()
{
localSMT = new VTEST_SUB();
}
}
public class LocalSMT<V>
{
public LocalSMT() { }
public virtual void doSomething(List<V> value) { }
}
public class VTEST_SUB : LocalSMT<int>
{
public VTEST_SUB(){}
public override void doSomething(List<int> value) {
System.Console.WriteLine("VTEST_SUB VIRTUAL");
}
}
class Program
{
Program() {}
static void Main(string[] args)
{
VTEST_RUN run = new VTEST_RUN();
}
}
The problem is that the VTEST_FSUB<V> constructor body is executing before the VTEST_RUN constructor body. So when do_virtual is called, localSMT is still null. Then do_virtual tries to call a method on localSMT, hence the exception.
Basically the initialization order for any class in the hierarchy is:
Initialize variables which have been declared within an initializer at the point of declaration (any other variables just have the variable type's default value)
Chain up to the base class initialization
Execute the constructor body
See my article on constructor chaining for more details.
Lessons to learn:
Avoid public fields. If you use private fields, it's easy to find every piece of code that reads them and writes to them
Ideally, use readonly fields: if you'd passed the value up the constructor chain and set it in the VTEST<V> constructor, you wouldn't have had a problem. (Admittedly readonly fields can still be a pain because of the next point...)
Avoid virtual method calls in constructors. In this case that wasn't the problem, but you could easily have had the same issue if do_virtual had been abstract in VTEST_FSUB<V> and overridden to call localSMT.doSomething in VTEST_RUN. It would still have executed before the constructor body had run, which would be surprising. Anything you call within a constructor is operating on a partially-initialized object, which is a precarious situation.
Avoid large inheritance hierarchies. They're a pain to work with and reason about.
Follow .NET naming conventions! Your code is partly hard to read because it's so unidiomatic. Even when you're just giving sample code, at least follow the capitalization conventions.
try:
public void do_virtual()
{
localSMT=new LocalSMT<V>();
localSMT.doSomething(list);
}
in public class VTEST_FSUB<V> : VTEST<V>
You are not instatianing localSMT before using, so it's not working.
EDIT: OR
public class VTEST<V>
{
public List<V> list;
public LocalSMT<V> localSMT;
public VTEST()
{
list = new List<V>();
localSMT = new LocalSMT<V>();
}
}
initialize it in constructor, preferable.
Second solution is cleaner.
public class VTEST_RUN : VTEST_FSUB<int>
{
public VTEST_RUN()
{
localSMT = new VTEST_SUB(); // BAD! localSMT isn't initialized yet!
}
}
I believe that you have failed to new up one of your objects:
public void do_virtual()
{
localSMT = new LocalSMT<V>();
localSMT.doSomething(list);
}
Make sure that when you are trying to use an object that you initialize them! And don't worry too much, this is a very common problem in coding.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why Would I Ever Need to Use C# Nested Classes
I'm doing it shorty, I have a class which looks like this:
namespace Blub {
public class ClassTest {
public void teest() {
return "test";
}
public class AnotherTest {
public void blub() {
return "test";
}
}
}
}
I can access to the function called "teest" like this, but how can I access to the function "blub" without doing another "new ClassTest.AnotherTest()"?
Accessing to the function teest:
Blub.ClassTest = new Blub.ClassTest();
ClassTest.teest(); //test will be returned
My try (and how I want it to, to access on AnotherTest is this:
Blub.ClassTest = new Blub.ClassTest();
ClassTest.blub(); //test will be returned
Which don't work, I can just access to AnotherTest like this, how I dont want it:
Blub.ClassTest2 = new Blub.ClassTest.AnotherTest();
ClassTest.blub(); //test will be returned
Does someone know a solutions for this?
You're declaring AnotherTest inside ClassTest, that's why you have to browse for it using namespace.class.2ndClass.
However, I suppose that you're not much aware of OO concepts, are you? If you declare a method inside a class, it will only be available for objects of that class, unless you declare it as static, what means that it would be a class method rather than a instance method.
If you want ClassTest to have 2 methods (teest and blub) simply declare both at the body of the class, like:
public class ClassTest
{
public string teest()
{
return "test";
}
public string blub()
{
return "test";
}
}
Also, note that if a method is declared as void it won't return anything (in fact, I think that your original code wouldn't even compile at all).
I'd recommend you to study OO a little deeper before trying to figure things out at your own.
If you need access to another class you have to make it a property in the first class.
namespace Blub {
public class AnotherTest {
public void blub() {
return "test";
}
}
public class ClassTest {
public AnotherTest at = new AnotherTest();
public void teest() {
return "test";
}
}
}
Then access it like this:
ClassTest x = new ClassTest();
x.at.blub();
This is probably easiest to explain with code (this is of course not the actual code but it has the same properties):
I have an interface that looks something like this:
public interface ISomeProvider
{
object GetFoo1(); //<-- This needs caching
//These others don't
object GetFoo2();
object GetFoo3();
//And let's say 20 more
}
And this has an implementation like this:
//NOTE: Sealed class otherwise we could inherit from it
public sealed class SuperCleverProvider : ISomeProvider
{
public object GetFoo1()
{
return "a";
}
public object GetFoo2()
{
return "b";
}
public object GetFoo3()
{
return "b";
}
}
Now one of these calls, let's say GetFoo1 is really heavy so I want to provider a new version of the interface where calls to it are cached using an instance of the old one.
I'm doing it like this at the moment:
public class CachedSuperCleverProvider : ISomeProvider
{
private readonly SuperCleverProvider _provider;
public CachedSuperCleverProvider(SuperCleverProvider provider)
{
_provider = provider;
}
private object UsingCache<T>(string cacheKey, Func<T> eval)
{
//Pretend this does caching. This is not related to the question
throw new NotImplementedException();
}
public object GetFoo1()
{
return UsingCache("foo1", _provider.GetFoo1);
}
//The code below this point is what I want to get rid of
public object GetFoo2()
{
return _provider.GetFoo2();
}
public object GetFoo3()
{
return _provider.GetFoo3();
}
//And so on for all the rest
}
This has two problems (at least):
Every time someone adds a method to the interface I have to go change this even though I dont want this new method to be cached
I get this huge list of useless code that just call through to the underlying implementation.
Can anyone think of a way of doing this that doesn't have these problems?
Three options:
Autogenerate the class
Use PostSharp or something similar to do it in a more interceptor-based way
Live with it
Personally I'd probably go with the third option, unless you really find yourself doing this a lot. Weigh up the cost of each option - how much time are you actually going to spend adding this delegation?
Personally I'd like to see this sort of thing as a language feature - "delegate to this interface via this field unless I override it" but obviously that's not present at the moment...
Here's what I'd suggest. It's not too much better, but will simplify the wrapping process.
Create a class SomeProviderWrapper:
public class SomeProviderWrapper : ISomeProvider
{
protected ISomeProvider WrappedProvider { get; private set; }
protected SomeProviderWrapper(ISomeProvider wrapped)
{
if (wrapped == null)
throw new ArgumentNullException("wrapped");
WrappedProvider = wrapped;
}
public virtual object GetFoo1()
{
return WrappedProvider.GetFoo1();
}
public virtual object GetFoo2()
{
return WrappedProvider.GetFoo2();
}
public virtual object GetFoo3()
{
return WrappedProvider.GetFoo3();
}
}
Now that the wrapping is relegated to its own class, you can write the caching version:
public class CachedSuperCleverProvider : SomeProviderWrapper
{
public CachedSuperCleverProvider(ISomeProvider wrapped) : base(wrapped) { }
private object UsingCache<T>(string cacheKey, Func<T> eval)
{
throw new NotImplementedException();
}
public override object GetFoo1()
{
return UsingCache("foo1", WrappedProvider.GetFoo1);
}
}
This keeps the delegation code out of your super clever provider. You will still have to maintain the delegation code, but it won't pollute the design of your caching provider.