I have developed the following class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace ESROWCFData
{
public class ESROWFCData
{
public string GetNCAMSData()
{
//int iOffset = 0, iTake = 0;
string strOffset = "iOffset", strTake = "iTake";
string strNCAMS = "SELECT * FROM[HRO_REPORTS].[dbo].NCAMS WHERE DATEPART(YEAR, VisitStartDate) = DATEPART(YEAR, GetDate()) ORDER BY VisitorID OFFSET " + strOffset + " rows fetch next " + strTake + " rows only";
return strNCAMS;
}
}
}
and have included the using ESROWCFData; statement in my main program but when I try to call the GetNCAMSData() function it does not show up and I get the error that it does not exist. I am obviously doing something wrong but I cannot see what it is.
You have two options here. You can either make the method static so you can call it without creating an instance of your class by changing the signature to be:
public static string GetNCAMSData()
Then call it like this:
var result = ESROWFCData.GetNCAMSData()
Or you could create a new instance of the class and then call it off that like follows
var instance = new ESROWFCData();
var result = instance.GetNCAMSData()
You first have to create an instance of the ESROWFCData class:
ESROWFCData data = new ESROWFCData();
and then use it:
string s = data.GetNCAMSData();
First of all your namespace and class name are the same :
namespace ESROWCFData
{
public class ESROWFCData
{
...
So even if you want to use this class outside you have to use full type name :
ESROWCFData.ESROWCFData data = new ESROWCFData.ESROWCFData();
In case you're trying to use it like such :
ESROWCFData data = new ESROWCFData();
Compiler then is confused because of that namespace name.
Consider name changes on the namespace or class to resolve that issue.
More about that issue
Another issue is ( the one we do not know much about ) how are you trying to call that object's method. If you want to just use them statically, mark it as static :
namespace ESROWCFData
{
public class ESROWCFData
{
public static string GetNCAMSData()
{
...
And you can call them like so : ESWROWCFData.ESWROWCFData.GetNCAMSData()
Related
I want to create a new class at runtime, get the type, and create a List of that type.
For example:
void CreateNewClass(string name)
{
File file = CreateFile(name);
Type type = GetTypeOfFile(file);
List<type> someList = new List<type>();
}
void CreateFile(string name)
{
//Get a template file
//copy that file
//change some names and stuff in it
//return the file
}
Type GetTypeOfFile(File file)
{
//get the class(type) of that file
// return type
}
I do not want to generate that class in memory, I need to have that class as a file.
The file creation is not a problem.
I just need to know:
How to load the file/class and get it's type
How to create a list with the loaded type
I guess something with Reflections need to happen, but after that I'm clueless.
edit:
FYI:
I don't actually want to create a List, I need this functionallity for a Unity Project.
For those who are familiar with it:
I want to create ScriptableObjects (the class itself and the asset) with one button click.
So I have a base class like:
public abstract class State : ScriptableObject{}
As you can see it's going to be a StateMachine. Now I want kind of a window with a text field where I enter a name for a state and it creates a new class like:
public class Idle : State{}
And after that it creates the asset itself via:
AssetDatabase.CreateAsset<Idle>("/path/to/somewhere");
edit nearly working code
using System;
using System.IO;
using System.Linq;
using System.Text;
using AI.StateMachine.BaseClasses;
using UnityEditor;
using UnityEngine;
namespace AI.StateMachine.Editor
{
public class ActionWizard : EditorWindow
{
[MenuItem("Tools/AI/StateMachine/ActionWizard")]
static void Init()
{
// Get existing open window or if none, make a new one:
ActionWizard window = (ActionWizard) EditorWindow.GetWindow(typeof(ActionWizard));
window.Show();
}
private string actionName;
void OnGUI()
{
actionName = GUILayout.TextField(actionName);
if (GUILayout.Button("Create Action"))
{
//Get base class content
string baseClassContent =
File.ReadAllText($"{Application.dataPath}/Scripts/AI/StateMachine/BaseClasses/SM_Action.cs");
//refactor base class content to create derived class content
string newClassContent = baseClassContent
.Replace("SM_Action", actionName)
.Replace("ScriptableObject", "SM_Action")
.Replace("abstract ", "")
.Replace("namespace AI.StateMachine.BaseClasses", "namespace AI.StateMachine.Assets.Actions.Scripts")
.Replace("//", "");
//create derived class
using (FileStream fs = File.Create($"{Application.dataPath}/Scripts/AI/StateMachine/Assets/Actions/Scripts/{actionName}.cs"))
{
byte[] info = new UTF8Encoding(true).GetBytes(newClassContent);
fs.Write(info, 0, info.Length);
}
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
//get type of created class
var allTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(assembly => assembly.GetTypes()).ToList();
var inputType = allTypes.Find(type => typeof(SM_Action).IsAssignableFrom(type) && type.Name == actionName);
//null....
//if type was created before it works and finds the desired type
Debug.Log(inputType);
//create scriptable object instance of created type
// var so = ScriptableObject.CreateInstance(inputType);
//save scriptable object asset
// AssetDatabase.CreateAsset(so,"Assets/Scripts/AI/StateMachine/Actions/"+actionName + ".asset");
// AssetDatabase.Refresh();
}
}
}
}
You can create type from string using:
Type.GetType(string typeAssemblyQualifiedName);
But you need to use Type.assemblyQualifiedName for that so "Idle" may not work if you use namespaces or assemblies, other option would be to get all types in current domains
var allTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(assembly => assembly.GetTypes());
and find your desired type on that list somehow
var inputType = allTypes.Find(type => typeof(State).IsAssignableFrom(type) && type.Name == inputName);
then we create scriptable object instance using that type
var so = ScriptableObject.CreateInstance(inputType);
I can't find this addressed on SO. I am porting a Windows .NET application, that compiles and runs perfectly, to Mono on Linux. I have missed something small. Here is a part of the code:
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace DAPTimeClock
{
public static class DatabaseOps
{
private static string _dbFile;
public static string Get_dbFile()
{
return _dbFile;
}
public void Set_dbFile(string value)
{
this._dbFile = value;
}
public static bool foundFile = false;
public static string SetFile(String dblocation = #"Data" +
"Source=../db/TimeClock.db; Version=3;")
{
Set_dbFile( dblocation );
int pathStart = Get_dbFile().IndexOf ('=') + 1;
int pathEnd = Get_dbFile().IndexOf (";") - 1;
string filePath = Get_dbFile().Substring (pathStart,
pathEnd - pathStart + 1);
if (File.Exists (filePath)) {
foundFile = true;
return string.Format ("The db file {0} has been " +
"located", filePath);
} else
{
foundFile = false;
return string.Format("Unable to find db file {0}.",
filePath);
}
}
public static bool AddPerson(Person p)
{
bool result = false;
Class Continues .....
Here are the issues:
Other classes can't find any methods from this class. ex. DatabaseOp.Set_dbFile() Yields no such method.
The methods in this class can't find methods from this class.
The methods in this class can't see the outside classes.
If I pass an argument to the methods in the class, the complier says it can't find a parameter by that name.
The methods in the class can't see its own member variables.
I have done the following:
I removed the static, now making regular objects. (no change)
I double checked the namespaces. (all the same, no typos)
I tried making the member variable public and adding a get; and set;
I am stumped. Can anyone see what might be hanging this up? Is there something about mono I missed? All other classes are working fine.
Set_dbFile should be declared as
public static void Set_dbFile(string value)
compiler should complain: "cannot declare instance members in static class". Have you miss this?
In my source code for a C# class, I want to use the values of parameters defined within some other class. I want to do it without "hardwiring" the other class name into the source code (e.g., without writing something like "class2.variable").
Rather, I want to pass the name of that other class as a character string at runtime.
I am using C# within Unity. So I want to set the name of the other class as a public string within the Inspector of Unity.
For example, consider these two separate scripts:
using UnityEngine ;
public class ScriptA : ScriptableObject {public static int fred = 5 ; }
and
using System;
using System.Reflection;
using UnityEngine;
public class ScriptB : MonoBehaviour {
object item;
private static string instance;
void Start() {
instance = "ScriptA";
item = ScriptableObject.CreateInstance(Type.GetType(instance));
Type myType = item.GetType();
foreach (FieldInfo info in myType.GetFields())
{
string infoName = info.Name; //gets the name of the field
Debug.Log (" info = " + infoName);
}
}
}
ScriptB works OK ; it accesses ScriptA just from the string "instance", as evidenced by the fact that
the name "fred" to appears in the console.
But how do I access the value of "fred" ; how do I make the number "5" appear on the console?
I have been trying for two days. I have searched extensively for an answer.
Can somebody please help?
FieldInfo has a GetValue method :
public abstract object GetValue(
object obj
)
Try:
Type myType = item.GetType();
foreach (FieldInfo info in myType.GetFields())
{
string infoName = info.Name; //gets the name of the property
Console.WriteLine(" Field Name = " + infoName +"and value = "+ info.GetValue(null));
}
I was wondering if it is possible to instantiate a class with a string variable as its name in C#. I don't know how else to explain it other than this.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
public class Product
{
string name;
decimal cost;
Product(string _name, decimal _cost)
{
name = _name;
cost = _cost;
}
}
class Program
{
static void Main(string[] args)
{
string nameForInstantiatedClass = "DellComputer";
Product nameForInstantiatedClass = new Product("Inspiron", 399.99m);
}
}
}
Is it possible to do something like this or to the same effect, using a string to declare the name of an instantiated class or is it just impossible to do? Any help is appreciated.
One thing that comes to my mind is to use a
var products = new Dictionary<string,Product>();
and then you can save / retrieve items like this
products.Add(nameForInstantiatedClass, ProductObject);
Product dellComp = products[nameForInstantiatedClass]
I don't know why you want to do that.
Is there an other logic for you?
You could put the instance in a List or Dictionary like :
Dictionary<String, Product> dict = new Dictionary()
dict.add("DellComputer", new Product("",399.99m);
I'm calling getName() method from Achiv class on an ArrayList in printAchiv() method located in Achievements script and it throws an error.
Here is the error message that I get on the line Debug.Log("Achiv "+i+": "+ achivList[i].getName());:
Type object' does not contain a definition for getName' and no
extension method getName' of type object' could be found (are you
missing a using directive or an assembly reference?)
I'm just trying to access value of var "name" from obejct in collection.
Achiv class :
using UnityEngine;
using System.Collections;
public class Achiv: MonoBehaviour
{
public string name;
public Achiv(string name)
{
this.name = name;
}
public string getName()
{
return name;
}
}
Achievements script :
using UnityEngine;
using System.Collections;
public class Achievements: MonoBehaviour
{
public ArrayList achivList = new ArrayList();
void Start()
{
achivList.Add(
new Achiv("First name", "Descirptionn", false));
achivList.Add(
new Achiv("Second name", "Descirptionnn", false));
printAchiv();
}
void printAchiv()
{
for (int i = 0; i <= achivList.Count - 1; i++)
Debug.Log("Achiv " + i + ": " + achivList[i].getName());
}
}
Use List<Achiv> instead of ArrayList. ArrayList is archaic, not type safe shouldn't be used anymore.
Indexer of ArrayList returns object that's why you get the error. Try the following.
public List<Achiv> achivList = new List<Achiv>();
Apart from this,
Don't expose List publicly, prefer ReadOnlyCollection or IEnumerable.
Prefer foreach over for unless there is a good reason.
printAchiv doesn't follow proper naming convention, In c# we use "CamelCase", Rename it to PrintAchiv.
get/set methods are for java style languages which doesn't supports properties. In c# we use properties instead. Create a property namely Name.
The problem is that the elements inside the ArrayList are stored as object. Thus achivList[i] returns an object, which does not provide the getName() method.
Either you can add a cast:
Debug.Log("Achiv "+i+": "+ (Achiv)achivList[i].getName());
or you can switch to a generic List:
using UnityEngine;
using System.Collections.Generic;
public class Achievements: MonoBehaviour {
public List<Achiv> achivList = new List<Achiv>();
void Start () {
achivList.Add (new Achiv("First name", "Descirptionn", false));
achivList.Add (new Achiv("Second name", "Descirptionnn", false));
printAchiv();
}
void printAchiv(){
for (int i = 0; i <= achivList.Count - 1; i++)
{
Debug.Log("Achiv "+i+": "+ achivList[i].getName());
}
}
}
ArrayList operates with Objects. You need to cast result of array indexing to Achiv:
(achivList[i] as Achiv).getName()