I'm going to try to explain this as best I can. I'm working on an application that needs to get data from another program. I have them all in the same solution I believe, I have the application referencing the .dll that has the variable i want in it.
the code is kinda set up like this
the .cs file that has the varible i want is set up like this
public class myObserverClass
{
//then there is a bunch of functions and the variable i need is in one like this
static void functionWithMyVariable(ref something, int toTier){
string myVariable = some value;
}
}
In my main application i need myVariable but i'm not sure how to access it. I have it using the namespace of the second program.
Have your function return the variable value you want rather than returning void.
static string functionWithMyVariable(ref something, int toTier){
string myVariable = some value;
return myVariable;
}
Also note that you need to make functions and (object/class level variables) PUBLIC if you want to access them from other projects.
myObserverClass.functionWithMyVariable();
Will not work unless functionWithMyVariable is a PUBLIC function.
public string functionWithMyVariable(ref something, int toTier){
Referencing an assembly (the .dll) in both applications is having them share code, which is not the same as sharing data. Each program will create individual in-memory versions of the classes and structures found in the .dll. See Transfer large data between .net applications on same computer for more info on how to transfer data between .net apps.
If I am not mistaken you have dll of an application say App1 having Class say C1 which is public. In this class you have a variable say V1.
Now you refer this dll into your another application say App2 where you want to access above said variable V2.
Now if the class C1 and the variable V1 both are public then you can access these like we access variables of one class to another into a single application by creating its object, but the condition is that both class and variable should be public.
Hope this can help you :)
Related
I am trying to pass the m_paths value from the class : ExtractDescriptorsForm.Cs to VisualizeFrom.Cs ..
This is how the variable is defined in ExtractDescriptorsForm.Cs :
namespace MediaLab.TopSurf
{
public partial class ExtractDescriptorsForm : Form
{
// list of paths that point directly at images, or at
// directories that contain images
List<string> m_paths;
public List<string> Paths { get { return m_paths; } }
......}}
What I wrote in VisualizeForm.Cs :
List<string> j = ExtractDescriptorsForm.m_paths;
The error is :
an object reference is required for the non-static field,method or property 'MediaLab.TopSurf.ExtractDescriptorsForm.m_paths'
To start, I need to make sure you understand something very fundamental here:
Files have nothing to do with this!
You're working with class objects, not files. You can have more than one ExtractDescriptorsForm showing the on the screen at the same time, and there's no reason this form needs to be in a file named ExtractDescriptorsForm.cs. In fact, you could put both the ExtractDescriptorsForm and the VisualizeFrom class definitions in the same file.
Learn this, and learn it well, or you'll struggle to ever be effective writing code.
Case in point... for this issue, the VisualizeFrom object is trying to look for the Paths property in a ExtractDescriptorsForm object... but which object? You're using class name here, when you need to be thinking about instances of the class.
I see the comments that you're trying to create a new ExtractDescriptorsForm object. This is probably a mistake. You very likely already have an instance in your program somewhere that you're already using, possibly created by code that Visual Studio provided for you. You need to find that existing reference.
I have a Control lblDate in User Control MainScreen. I would like to modify it in a method in class Date, which is in another project AoWLibrary. I can't reference it because AoWLibrary is a dependent of the first project.
I tried to make lblDate static but the compiler kept throwing errors at me, and I have a public property that Date can't seem to access:
public Label LabelDate
{
get { return lblDate; }
set { lblDate = value; }
}
In class Date, I need public method CalculateDate to modify the Text property of lblDate
public static void CalculateDate()
{
GameDate = month.ToString() + "/" + displayDay.ToString() + "/" + year.ToString();
// LabelDate.Text = GameDate;
// This is essentially what I need to do
}
Also, I can't even access lblDate in other controls in the same project.
So, the general idea is that you need to keep track of what is in scope. There are a lot of ways to go about doing what you want to do, but any of them rely on objects referencing each other properly in ways you may not quite understand fully yet. Don't worry-- everyone has to work through this at some point.
The reason the compiler complained when you tried to make that member static is because the label itself is not static. Being tied to a single instance of MainScreen, it has no meaning in a static context, which is by definition a scope without any inherent reference to a particular MainForm.
Your Date class is, of course, a totally different context, too, but its non-static members do have access to an instance of Date. There isn't any path between these two contexts until you create it. The static route actually would have worked (look up the Singleton pattern: the idea being that you store the first and only instance of a class statically and refer to it from elsewhere) but is probably not good design. Other ways to do this are by passing to Date an instance of MainScreen (preferably through an interface) or even LabelDate itself. All of these could get the two pieces you need together to talk.
However, I would like to suggest you think about where your game state is being stored. Is it in the library or the consuming assembly? If the former, you might want to think about creating a complete GUIless model of the data that needs to be stored and manipulated in the library class and only consume that ready-made data as-is in the main application. The other alternative is that your model lives in the main application, and just calls back to your library as necessary. In this case you should probably stick for now to asking the library for answers (or at most listening for events in the library) and NOT expecting it to reach back to the application on its own (whether to get or provide information).
In figuring out how to do this you will probably find your scope management issues are much easier to handle. Even a little bit of good architecture can go a long way.
But if this is all a little overwhelming, don't stress it too much. It sounds like you are doing this for fun, which is a great way to learn. You'll come up against issues like this and will either hit on a good design or a not-so-good one, but either way you're wrestling with important concepts and will come away better for it.
the propertie LabelDate is from the class of your userControl MainScreen, but you're not instatiating any userControl.. Which instance of MainScreen do you expect to modify then?
you should do
this.controlMainScreen.LabelDate = GameDate;
considering that you say in your comments, that you have
FormMain.Designer.cs there is: this.controlMainScreen = new Adventurers_of_Wintercrest.UserControls.MainScreen();
I'd rather advise you make your GameDate method to return a string then call it from your main project which are essentially what libraries are meant for. e.g.:
public static string CalculateDate()
{
return month.ToString() + "/" + displayDay.ToString() + "/" + year.ToString();
}
//in your main project
LabelDate.Text = myLibrary.CalculateDate();
For accessing it from other controls in the same project, you should use a delegate - Provide a delegate which performs the addition, declare the delegate and invoke the function from your CaculateDate. Example:
public delegate void dateSet(string);
public void setDate(string date)
{
labelDate.Text = date;
}
then in your CaculateDate method:
labeldate.Invoke(new MainForm.dateSet(), GameDate);
I tried to ask a question yesterday but it was seemingly too vague. Here's another try.
In the past, I have used some winforms/VB.Net classes with functionality for, say, working on text strings, for file operations, or for database handling, like clsStrings, clsIO and clsDB. The idea was that these classes did everything related to the subject, so that clsStrings would have a method called "filterString", removeCertainChars" etc.
In the old winforms application, I simply wrote Imports clsStrings when I needed to access a method. Throughout the .vb file, I could then write something like
str = filterString(TextBox1.Text)
I now try to get the same functionality in a new winforms app in C#. The only thing I get to work is creating a variable for the class:
clsStrings clsstrings = New clsStrings();
...and then later in the code:
str = clsstrings.filterString(TextBox1.Text);
So I guess what I would want is the ability to use a using statement for these "helper classes" (is there a better word for them?) so that I wouldn't have to write the variable name all the time. (Just like when Intellisense discovers that a namespace is missing and asks if I want to have a using statement for, say, System.Data so I can write "DataTable" instead of having to write "Data.Datatable" all the time.)
I suspect I would need to put these class files in a separate folder or so, but that would be totally fine. I just want some structure to my app.
I hope this is clearer.
Thanks for any input!
Well, the difference is that now you are working with OOP principles.
What you could do to be closer to what you were used to is to build static classes for the helper class, maybe even turn them into extension methods.
Example:
public static class ClsStrings
{
public static string FilterString(this string stringToFilter) { return something; }
}
Then you could call it like this:
string filteredString = TextBox1.Text.filterString();
or
string filteredString = ClsStrings.filterString(TextBox1.Text);
Extension methods is the way to go here. Using these you can basically exten String class with your own methods and do something like Sting.filterString();
http://msdn.microsoft.com/en-us/library/vstudio/bb383977.aspx
i am trying to instatiate a public sealed class in my program,
the thing is, ...as i am still fresh C# .net not-yet Developer , i find this issue a little difficult ...
As for the problem in Question, you can skip straight to Program example, or read the folowing background:
DB_Schema is a helper namespace, i've Created, to deal with the data accessing
(it holds tables And SPs names ..etc')
one of its classes(below) deals with Stored Procedures, and this one holds names of SPs Parameters
public sealed class SProc
{
public sealed class GetCPAReport
{
public const string RecordNum = "#RecordNum",
CPAColumnName = "#CPAColumn_Name",
Value = "#value",
IsFreelance = "#isFreelance";
}
}
Usage in program:
within method for data access via SP
private DataTable Get_RefTable_OfUsersBy(string DepartmetID)
{
SProc.GetCPAReport SProcGetCpa = SProc.GetCPAReport();
SP_Params.Add(new SqlParameter(SProcGetCpa.IsFreelance, 1));
}
trying to access one of the instance (SProcGetCpa) members is not possible the way i tried .
i could just make class SProc + it's sub class UpdateCPAReport not sealed and ...
but as i was searching the question "can sealed class be instantiated?
well.. the answer is Yes ... though trying to find information on the error:
cannot be accessed with an instance reference; qualify it with a type name instead
yields no results, Nor an Example of Accessing Instantiated sealed class public member code
atleast not for fresh .net C#arpers like me
- Update
i wanted to avoid long lines and make custom short names for the strings that represents the stored procedure name
instead of
ParListEmployeeUsrs.SP_Params.Add(new SqlParameter(HTSPs.RobTC_CPA_Users_Names_JobPosition.IsFreelance, SelectedDepartmentID));
update 2
for future comers on this subject who seeks for an answer
as suggested by a dear friend of ours, here in StackOverflow
if you do have to make a short namings for your classes, when using them for current peoject :
just place this among the usings of your project
using system...
using restOf.net
//just add your own as follows !
using shortClassName = myHelperNameSpace.MyIncrediblyUnnecessaryLongHelperClassName;
GetCPAReport doesn't have any instance members. const members are implicitly static. In C#, you can't access static members through a reference as you're trying to at the moment.
You just want:
SP_Params.Add(new SqlParameter(SProc.GetCPAReport.IsFreelance, 1));
Personally I'd make GetCPAReport a static class, too. There's no point in instantiating it, as it just contains constants... so actively prevent it from being instantiated.
I am making a program which makes use of a couple of constants. At first, each time I needed to use a constant, I'd define it as
//C#
private static readonly int MyConstant = xxx;
//Java
private static final int MyConstant = xxx;
in the class where I'd need it. After some time, I started to realise that some constants would be needed in more than one class.
At this time, I had 3 choises:
To define them in the different classes that needed it. This leads to repetition. If by some reason later I need to change one of them, I'd have to check in all classes to replace them everywhere.
To define a static class/singleton with all the constants as public.
If I needed a constant X in ClassA, ClassB and ClassC, I could just define it in ClassA as public, and then have ClassB and ClassC refer to them. This solution doesn't seem that good to me as it introduces even more dependencies as the classes already have between them.
I ended up implementing my code with the second option.
Is that the best alternative? I feel I am probably missing some other better alternative.
What worries me about using the singleton here is that it is nowhere clear to a user of the class that this class is using the singleton. Maybe I could create a ConstantsClass that held all the constants needed and then I'd pass it in the constructor to the classes that'd need it?
Thanks
edit: I'm using this mostly for complex types, not ints and strings. At least in the C# case that makes a difference as it means I can't use the const keyword.
No wording about C#, but in Java there are several ways to solve this problem.
Change the access modifier to default (package-only) or public. The most straightforward solution.
Group them in a package-private or public enum. Most straightforward if those values are related to each other. E.g. Role.ADMIN, Role.USER, Role.GUEST, etc.
Declare them in a package-private or public interface and let the classes implement it. Only do this if those constants belong to some contract the classes have to adhere as well.
Put them in properties files and load as private static final Properties and add a public static String getProperty(String key). Wrap this in some package-private or public Configuration class. More useful if those constants might be sensitive to changes which you could then control externally.
Constants doesn't require to be accessed by an instance, so the whole singleton idea makes no sense.
Use a properties file and put the constants in there.
ConfigurationManager.AppSettings Property in .Net exists for just this reason. You put the settings into config files assuming that these are elements that you want to be set in one place,e.g. for a website using ASP.Net the web.config is one location where settings can be placed so that development, test and production environments can each have different settings in how they run.
As far as int is concerned I usually use an enum in C#
public enum MyMagicNumbers
{
TheFirst = 1,
TheSecond = 2,
TheLast = 10,
}
For other types - like BalusC already mentioned - a sealed class is all you need
public sealed class MyMagicStuff
{
private MyMagicStuff() {}
public const string TheFirst = "One";
public const string TheSceond = "Two";
public const string TheLast = "Ten";
}
I'd define it in one place, in one of the classes that needed it. I'd make it static and final and public so it was true constant, accessible by any other client that needed it.
One approach to this would be to use Spring, available in both Java and .NET.
www.springsource.org
www.springframework.net - .net
Otherwise I'd use a config file.