This seems like an odd request, I appreciate that, but this is the situation:
I have a program which depends on reading in a handful of files. These files are named like: foo_bar_BAZ.txt where BAZ is the name of the project and not known until run-time. However it will not change for the entire execution of the program.
I want to have an enumerated list of strings which stores all the filenames. So far I have used a sealed class like so:
public sealed class SQLFile
{
private readonly String name;
private readonly String value;
public static readonly SQLFile CrByAuthors = new SQLFile("Changes_CR_By_Authors_%project_name%.txt", "CrByAuthors");
public static readonly SQLFile DocumentCrMetrics = new SQLFile("Changes_Document_CR_Output_%project_name%.txt", "DocumentCrMetrics");
[...]
private SQLFile(String value, String name)
{
this.name = name;
this.value = value;
}
public String ToString(string projectName)
{
return this.value.Replace("%project_name%", projectName);
}
}
As you can see this depends on my providing the project name variable every time I want to access the filename, even though that filename is really constant from the very beginning of run-time till the end.
Is there a more elegant way to handle with this situation?
A simple solution would be to have a static class with a ProjectName property. The value of this property is set during startup of the application. Your class then can use that property.
Add a static property to SQLFile, something like
public sealed class SQLFile
{
//...
private static string sProjectName;
public static string ProjectName
{
get
{
return sProjectName;
}
set
{
//optionally, you could prevent updates with:
//if (string.IsNullOrEmpty(sProjectName))
sProjectName= value;
//else throw Exception("ProjectName was already set!");
}
}
[Edit - I read the code a bit too fast, so this is what I actually meant:]
The purpose of the (poorly named IMHO) method ToString is to return the name of a file corresponding to a certain project name. There is nothing wrong with that, although it may be a responsibility which might belong to a separated class.
You could, for example, refactor the code to express its intention more clearly:
interface ISqlFileNameProvider
{
string SqlFilename { get; }
}
Then have a simple ("poor man's") implementation:
public class SimpleSqlFileNameProvider : ISqlFileNameProvider
{
private readonly string _filename;
public SimpleSqlFileNameProvider(string filename)
{
_filename = filename;
}
public string SqlFilename
{
get { return _filename; }
}
}
And then derive specialized implementation from here:
public class TemplateSqlFileNameProvider : SimpleSqlFileNameProvider
{
public TemplateSqlFileNameProvider(string template, string projectName)
: base(template.Replace("%project_name%", projectName))
{ }
}
public class CrByAuthorsFileNameProvider : TemplateSqlFileNameProvider
{
public CrByAuthorsFileNameProvider(string projectName)
: base("Changes_CR_By_Authors_%project_name%.txt", projectName)
{ }
}
public class DocumentCrMetricsFileNameProvider : TemplateSqlFileNameProvider
{
public DocumentCrMetricsFileNameProvider(string projectName)
: base("Changes_Document_CR_Output_%project_name%.txt", projectName)
{ }
}
First, note that projectName remains the parameter for the constructor of these specialized classes. There are no globals here. Next, even though you've added a bit of plumbing code to your project, it's easier to decouple your classes for simpler testing: you can create a mocked implementation of ISqlFileNameProvider and return whatever you like to test the rest of the functionality without writing to real data files.
I would certainly advise against using a global property. The fact that you can specify the project name as a constructor parameter means that you can easily test that your class behaves the way you want it to. And even though you think that it will change during project lifetime, you can easily encounter a scenario where you temporarily need to switch the project name in runtime. I would advise against using globals.
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.
Trying to get the reason behind it.
Scenario#1
public class Customer
{
string _name = "Ram";
//now trying to assign some new value to _name on the next line
_name // this property is inaccessible on this line.
}
Scenario#2
public class BaseCustomer
{
protected string _name;
}
public class DerivedCustomer : BaseCustomer
{
_name //inaccessible here
public void SetName()
{
_name = "Shyam"; //accessible here
}
}
Can somebody please let me know what is cause behind this??
Simple. You can't make variable assignments (without declaration) in the class context. You need to use a constructor to put the assignment in:
public class DerivedCustomer : BaseCustomer
{
public DerivedCustomer()
{
_name = "hello";
}
...
}
... or put it in the declaration:
public class BaseCustomer
{
protected string _name = "hello";
}
Note: Experts will probably find exceptions to my simplified explanation. I'm keeping it simple for the sake of explaining the key intention to OP.
In a way, a class really only contains declarations. This can be a field:
public class Customer
{
private string _name;
}
Or a property:
//Example 1 - Simple property
public class Customer
{
public string Name { get; set; }
}
//Example 2 - Publically gettable (but not settable) property with private field (which is settable)
public class Customer
{
private string _name; //this is a field
public string Name => _name; //this is a property that relies on the field
}
Or a method:
public class Customer
{
public string GetName()
{
return "John";
}
}
Boiling it down, I would summarize it as follows:
A class only contains declarations of how it is structured: fields, properties, methods.
A class does not directly contain code (i.e. logic which uses the fields/properties).
However, a class' method or property can contain code (i.e. logic which uses the fields/properties), but this code is considered to be part of the method/property, not part of the class (directly).
What you're trying to do doesn't quite make sense to me. I'm not quite sure what you're hoping to achieve by trying to access the _name in those locations.
It only makes sense to reference this field in the locations where you can reference it:
In a method body - If you need the field during the method's execution
In a property - When the field is used during the set/get of a property
In a constructor - To set the value of the field.
But you're trying to put in in the class. This raises many questions:
What are you trying to do with _name?
Assuming you could reference the field where you want to; when are you expecting this code to be executed?
How would this be any different from simply using a method (or the constructor)?
I have created an engine that takes in 3rd party plugins (DLL's) that implement an interface.
Since I have no control over the code that gets plugged in, I want to be able to run 1 specific method (from the interface) from the correct class (GetTypes loop untill I find the interfaced class ).
Since anyone can create nice constructor code that executes on Activator.CreateInstance, I can solve that by using FormatterServices.GetUninitializedObject. But that does not help when code is being initialized on fields in the class.
public class myclass : myinterface {
public someotherclass name = new someotherclass()
public myclass() {
//Unknown code
}
//I only want this run.
public string MyProperty{
get {
return "ANiceConstString";
}
}
}
The problem with both ways (CreateInstance/GetUninitializedObject) is that the constructor of someotherclass will be run.
Before you start analyze my needs. This is only run in the initializing of the engine to get a set of standard values. If this get'er relies on other initialized values the "plugin" will be marked as failed as there is no valid value returned. If not marked as failed, later on the class will be loaded properly with Activator.CreateInstance().
So stick to this question:
Does .Net support any way to create an 100% non-initialized class?
Update for the answers. I tested this before I posted my question.
For the answer that someotherclass wont run, I allready tested that and it is run if static.
public class myclass : myinterface {
static Tutle test;
public myclass () {
test = new Tutle();
}
public class Tutle {
public Tutle() {
MessageBox.Show("RUN!");
}
}
}
CreateInstance shows the messagebox. GetUninitializedObject does not.
public class myclass : myinterface {
static Tutle test = new Tutle();
public myclass () {
}
public class Tutle {
public Tutle() {
MessageBox.Show("RUN!");
}
}
}
CreateInstance shows the messagebox. GetUninitializedObject shows the messagebox.
Is there a way to get around static field intializers and ctors?
Simply:
var obj = (myclass)FormatterServices.GetUninitializedObject(typeof(myclass));
That will not run the constructor / field initializers. At all. It will not run the constructor for someotherclass; name will be null.
It will, however, execute any static constructor that exists, if necessary under standard .NET rules.
HOWEVER! I should note that this method is not intended for ad-hoc usage; its primary intent is for use in serializers and remoting engines. There is a very good chance that the types will not work correctly if created in this way, if you have not subsequently taken steps to put them back into a valid state (which any serializer / remoting engine would be sure to do).
As an alternative design consideration:
[SomeFeature("ANiceConstString")]
public class myclass : myinterface {
public someotherclass name = new someotherclass()
public myclass() {
//Unknown code
}
}
Now you can access the feature without instantiation; just use:
var attrib = (SomeFeatureAttribute)Attribute.GetCustomAttribute(
type, typeof(SomeFeatureAttribute));
string whatever = attrib == null ? null : attrib.Name;
with:
[AttributeUsage(
AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum)]
public sealed class SomeFeatureAttribute : Attribute
{
private readonly string name;
public string Name { get { return name; } }
public SomeFeatureAttribute(string name) { this.name = name; }
}
We have a functions library and some utility variables are stored in two diferent ways depending on the app context desktop app/website
In website we use Sessions and in desktop static variables and we would like to unite and automatize the getters//setters for those variables without affecting performance too much
Example:
public static class Cons
{
public static bool webMode;
}
public static class ConsWEB
{
public static string Username
{
get{ return HttpContext.Current.Session["username"].ToString();}
set{ HttpContext.Current.Session["username"]=value;}
}
}
public static class ConsAPP
{
private static string _username;
public static string Username
{
get{ return _username;}
set{ _username=value;}
}
}
Solution 1 we thought, using IFs (seems bad for performance, take into account accessing variables lots of times, and in some cases the variables are custom classes with complex contents):
public static class Cons
{
public static bool webMode;
public static string Username
{
get{ return webMode? ConsWEB.Username : ConsAPP.Username; }
set
{
if(webMode) { ConsWEB.Username = value; }
else { ConsAPP.Username = value; }
}
}
}
Solution 2 using delegates, at the Static Class constructor associate delegated methods to each get and set depending on the case. If is webMode point to the get/set methods of ConsWEB, otherwise to the get/set methods of ConsAPP...
Is the solution 2 the best one performance-wise? Are there other methodologies for this cases?
Neither is optimal...
First, forget about performance think design first.
You should do it through an interface or similar:
public interface IConsProvider
{
string UserName { get; set; }
}
Now your implementations (NOTE: you should not really be compiling for both desktop and web in the same assembly. System.Web, for example, is not available in Client Profile - which you should really use for desktop apps).
public class WebConsProvider : IConsProvider
{
public string UserName
{
// DON'T USE .ToString()! If it's null you get NullReferenceException!
get{ return HttpContext.Current.Session["username"] as string; }
set{ HttpContext.Current.Session["username"]=value; }
}
}
public class DefaultConsProvider : IConsProvider
{
public string UserName
{
get; set;
}
}
And then your environment static:
public static class Cons
{
//initialise to default as well - only web apps need change it
private static IConsProvider _provider = new DefaultConsProvider();
public static IConsProvider Provider
{
get { return _provider; }
set { _provider = value; /* should check for null here and throw */ }
}
//if you really want you can then wrap the properties
public static string UserName
{
get {
return _provider.UserName;
}
set {
_provider.UserName = value;
}
}
}
Now you have an extensible provider whose implementation you do not need to worry about.
I do personally also have an issue with wrapping HttpContext.Current - however in most scenarios that does work fine - if you have any asynchrony going on, however, then you have to be careful.
Also - as I mention in my comments - you no longer need to wrap the properties as statics in Cons now. Indeed you gain an awful lot of testability and extensibility by changing code like this:
public void TraceUserName()
{
Trace.WriteLine(Cons.UserName ?? "[none]");
}
To this:
public void TraceUserName(IConsProvider provider)
{
Trace.WriteLine(provider.UserName ?? "[none]");
}
Believe me there will be times in your code where you'll wish "just for this call I'd like to override the UserName - but I can't, because it's a static property".
Finally you now have another extensibility mechanism at your disposal that you don't with statics : extension methods.
Say you add a common storage mechanism to the interface for strings:
string this[string key] { get; set; }
So that's a string indexer, allowing us to implement a dictionary-like functionality for unforeseen values. Assume they've both been implemented, with a Dictionary<string, string> in the DefaultConsProvider and wrapping the Session in the WebConsProvider).
Now if I'm writing an additional module for your project that needs some additional string value - I can do this:
public static MySettingsExtensions
{
public static string GetMySetting(this IConsProvider provider)
{
//TODO: argument null checks
return provider["MySetting"];
}
public static void SetMySetting(this IConsProvider provider, string val)
{
provider["MySetting"]=val;
}
}
(Sorry had to update that last bit as for some reason I parameterised the key - which was pointless!)
That is - we can now start extending the range of strongly-typed settings offered by the provider via extension methods - without having to alter any of the original code.
I hate writing repetitive code....
In my current project I need to write properties that looks the same in each class, but different from class to class.
My wish is to generate custom properties from private memeber variables. Lets say I have declared a Name variable like this.
private string Name;
In my first class I want to automagically generate a property like this:
private string m_name;
public string Name
{
get
{ return m_name; }
set
{
m_name = value;
// some code....e.g.
m_counter++;
}
And maybe I want another implementation in my second class, e.g.
private string m_name;
public string Name
{
get
{ return m_name; }
set
{
// some code....e.g.
if(MyValidationFramework.Validate("Name", value))
{
m_name = value;
}
}
I know I can create my own snippets. Since I often change the property-implementation I'd like a way to generate the properties from a template, then change the template and generate properties again. Can this be done?
Thanks!
This is not direct answer to you question. However, with the example you show, why not to have a base class and inherit from it, like this:
public abstract class BaseClass
{
private string m_name;
public string Name
{
get { return m_name; }
set
{
if (BeforeNameSet(value))
m_name = value;
}
}
public virtual bool BeforeNameSet(string name)
{
return true;
}
}
public abstract class ChildClass : BaseClass
{
public override bool BeforeNameSet(string name)
{
// do the part that is different
return false;
}
}
[Edit]
I see you that snippets are not an option for you.
You could create an item template, (How to: Manually Create Item Templates), but in the end this is even more effort as you want to be able to dynamically update those. Item template is a zip file, that you would need to change content for.
Seems like copy/paste is your best option then.