instantiate subclass by string na C# - c#

I have a Class and a Sub Clas
namespace MyCode
{
public class Class1
{
int a = 1;
int b = 2;
public class SubClass1
{
int a = 1;
int b = 2;
}
}
}
Now I need to instantiate each class by string name. I can do this from the class, but not for the subclass.
This works:
var myObj = Activator.CreateInstance(Type.GetType("MyCode." + "Class1"));
But this, din´t work:
var myObj = Activator.CreateInstance(Type.GetType("MyCode." + "Class1.SubClass1"));
What I need to do for the second option?

Whenever you don't know what a name should be you can see the name by checking typeof(MyCode.Class1.SubClass1).FullName.
When you have a subclass you use the + sign.
var myObj = Activator.CreateInstance(Type.GetType("MyCode." + "Class1+SubClass1"));

var myObj = Activator.CreateInstance(Type.GetType("MyCode.Class1+SubClass1"));
Its + when dealing with nested types, not .

Related

I got this error CS0103 and I don't know if this is from C# extension or if I forget to put something

I don't know if this is an error with the C# extension or I just forgot something.
I was trying to make a health base system so I convert into a string to print the number then back to int, to its original form.
FYI this some of my code, not all of it another thing I know their other forms but it wasn't looking for.
Example 1
example 2
class Conehead_Wizzard
{
public string name;
public string ConeHead_Powerful_spells;
public int slots;
public float Level_Up;
public int Player_Health;
public int Chance;
public int b;
public int c;
public Conehead_Wizzard(string _name, string _ConeHead_Powerful_spells,
int _Player_Health)
{
name = _name;
ConeHead_Powerful_spells = _ConeHead_Powerful_spells;
slots = 5;
Level_Up = 1.2f;
Player_Health = 1000;
b = 100;
void Damage_Chance ()
{
Random Chance_ = new Random();
int Chance = Chance_.Next(0, 100);
if (Chance > 99)
{
System.Console.WriteLine(Player_Health - b);
System.Console.WriteLine("you lost" + Player_Health + "of your health");
Player_Health--;
string a = Convert.ToString(Player_Health);
}
else
{
System.Console.WriteLine("Miss!, next player");
c = Convert.ToInt16(Player_Health);
}
}
}
}
class Program
{
static void Main(string[] args)
{
Conehead_Wizzard wizzard = new Conehead_Wizzard("Cone_Head ",
"The Cone of time &" + " Cone of shield", Player_Health);
}
}
You haven't declared the variable Player_Health in the Main method. Did you maybe intend to do something as follows:
static void Main(string[] args)
{
int Player_Health = 1000;
Conehead_Wizzard wizzard = new Conehead_Wizzard("Cone_Head ", "The Cone of time &" + " Cone of shield", Player_Health);
}
Although this should allow you to compile, be aware, the constructor isn't using the value passed into _Player_Health. It just sets wizzard.Player_Health to 1000. If you want to use it, you need to change your constructor to something like this:
public Conehead_Wizzard(string _name, string _ConeHead_Powerful_spells, int _Player_Health)
{
name = _name;
ConeHead_Powerful_spells = _ConeHead_Powerful_spells;
slots = 5;
Level_Up = 1.2f;
Player_Health = _Player_Health;
b = 100;
}

C# accessing class instance from method

Seems like I'm struggling with a pretty basic problem right now, but I just can't find a good solution..
I have this code-snippet here:
public Form1()
{
InitializeComponent();
BaseCharacterClass myChar = new BaseCharacterClass();
}
public void setLabels()
{
lbName.Text = myChar.CharacterName;
lbHealthPoints.Text = (myChar.CharHPcurrent + "/" + myChar.CharHPmax);
lbMagicPoints.Text = (myChar.CharHPcurrent + "/" + myChar.CharMPmax);
lbClass.Text = myChar.CharacterClass;
}
It says "myChar" does not exist in the current scope..
How do I fix that?
You just need to declare myChar outside of the constructor. You can define it on the class and then assign it on the constructor:
BaseCharacterClass myChar;
public Form1()
{
InitializeComponent();
myChar = new BaseCharacterClass();
}
public void setLabels()
{
lbName.Text = myChar.CharacterName;
lbHealthPoints.Text = (myChar.CharHPcurrent + "/" + myChar.CharHPmax);
lbMagicPoints.Text = (myChar.CharHPcurrent + "/" + myChar.CharMPmax);
lbClass.Text = myChar.CharacterClass;
}
You didnt declare the variable as a class variable, only a local one. In c# the format is:
MyNamespace
{
class MyClassName
{
//class wide variables go here
int myVariable; //class wide variable
public MyClassName() //this is the constructor
{
myVariable = 1; // assigns value to the class wide variable
}
private MyMethod()
{
int myTempVariable = 4; // method bound variable, only useable inside this method
myVariable = 3 + myTempVariable; //myVariable is accessible to whole class, so can be manipulated
}
}
}
And so on. Your current constructor only declares a local variable within the constructor, not a class wide one

Accessing generic object in generic list in C#

I am relatively new to C# and I would like to create a list of generic objects.
Here is how I try to do it:
I create a base class:
public class BaseClass
{
}
And I inherit a generic class from the base class:
public class GenericClass<T> : BaseClass where T: struct
{
public T data;
public GenericClass(T value)
{
data = value;
}
public T doSomething()
{
return (T)(data * (dynamic)0.826f);
}
}
Then I can create a list of base class:
List<BaseClass> ListOfGenericClasses = new List<BaseClass>();
And I can add instances of the inherited geneic class:
ListOfGenericClasses.Add(new GenericClass<int>(100));
ListOfGenericClasses.Add(new GenericClass<byte>(101));
ListOfGenericClasses.Add(new GenericClass<float>(10.1f));
ListOfGenericClasses.Add(new GenericClass<double>(100.10));
ListOfGenericClasses.Add(new GenericClass<ulong>(9999999999));
ListOfGenericClasses.Add(new GenericClass<long>(-9999999999));
ListOfGenericClasses.Add(new GenericClass<uint>(62389));
ListOfGenericClasses.Add(new GenericClass<sbyte>(-103));
I also can invoke each objects method:
string s = "";
s += ((GenericClass<int>)(ListOfGenericClasses[0])).doSomething() + " # ";
s += ((GenericClass<byte>)(ListOfGenericClasses[1])).doSomething() + " # ";
s += ((GenericClass<float>)(ListOfGenericClasses[2])).doSomething() + " # ";
s += ((GenericClass<double>)(ListOfGenericClasses[3])).doSomething() + " # ";
s += ((GenericClass<ulong>)(ListOfGenericClasses[4])).doSomething() + " # ";
s += ((GenericClass<long>)(ListOfGenericClasses[5])).doSomething() + " # ";
s += ((GenericClass<uint>)(ListOfGenericClasses[6])).doSomething() + " # ";
s += ((GenericClass<sbyte>)(ListOfGenericClasses[7])).doSomething();
MessageBox.Show(s);
And here comes the question: how do I get the value of each instance in the list generally?
I try to do something like this:
string s = "";
for (int i = 0; i < ListOfGenericClasses.Count; i++)
{
s += ((GenericClass<ListOfGenericClasses[i].GetType().GetGenericArguments()[0]>)(ListOfGenericClasses[i])).dosdoSomething() + " # ";
}
MessageBox.Show(s);
I have the following error message: "Using the generic type 'GenericClass requires 1 type argument'"
EDIT: sorry guys I could have been more precize when asking my question: my point was not to use the return value to build a string it was just for seeing the result on screen
Any help is much apreciated,
Thanks in advance
I'd approach it in a slightly different way:
public class BaseClass
{
public virtual string DoSomethingToString() { throw new NotImplementedException(); }
}
Then you'd implement your derived class as follows:
public class GenericClass<T> : BaseClass where T: struct
{
public T data;
public GenericClass(T value)
{
data = value;
}
public T DoSomething()
{
return (T)(data * (dynamic)0.826f);
}
public override string DoSomethingToString()
{
return DoSomething().ToString();
}
}
Now you can iterate List<BaseClass> and directly call each element's DoSomethingToString() method.
Does this do what you want?
string s = "";
for (int i = 0; i < ListOfGenericClasses.Count; i++)
{
Type type = ListOfGenericClasses[i].GetType();
dynamic d = Convert.ChangeType(ListOfGenericClasses[i], type);
s += d.doSomething() + " # ";
}
It looks like you are trying to implement a union type. I am sure there must be better ways than this.
Should you use Generics? I re-wrote your app and solved the problem by removing Generics
public class GenericClass : BaseClass
{
public object data;
public GenericClass(object value)
{
this.data = value;
}
public object doSomething()
{
return (object)(this.data * (dynamic)0.826f);
}
}
Then I did it:
for (var i = 0; i < ListOfGenericClasses.Count; i++)
{
s += ListOfGenericClasses[i].doSomething() + " # ";
}
You would need to use reflection to get the type and then from that get the method which you can then invoke:
string s = "";
for (int i = 0; i < ListOfGenericClasses.Count; i++)
{
s += ListOfGenericClasses[i].GetType()
.GetMethod("doSomething")
.Invoke(ListOfGenericClasses[i], null);
}
However, I would recommend you take the approach as suggested by #corak in the comments and by #InBetween in their answer and create a virtual method in BaseClass and override it in GenericClass.
First use stringBuilder to concat strings, you can cast your object to dynamic to invoke the method you need dynamically:
var stringbuilder = new StringBuilder();
foreach (var l in ListOfGenericClasses)
{
var st = (l as dynamic).doSomething() + " # ";
stringbuilder.Append(st);
}
MessageBox.Show(stringbuilder.ToString());

LINQ - adding function to datacontext

I have a linq table "KUND" who is read only to me. It has some special characters in it to which i have writter a function to switch them out to the ones i want.
public static string changeSpecialCharacters(string kund)
{
StringBuilder b = new StringBuilder(kund);
b = b.Replace("Õ", "å");
b = b.Replace("┼", "Å");
b = b.Replace("õ", "ä");
b = b.Replace("─", "Ä");
b = b.Replace("÷", "ö");
b = b.Replace("Í", "Ö");
b = b.Replace("'", " ");
b = b.Replace("¦", "´");
b = b.Replace("Ï", "Ø");
return b.ToString();
}
I now have two questions:
1 Can i add this function to the GET in the autogenerated datacontext so i dont have to call it all over my code? Ive added it but it seems to be deleted whenever i change how my datacontext is (add/remove table). 2 Any suggestions how to make that function better in regards to speed perhaps?
Never edit the .designer.cs; instead, add a second file, and use partial class to add the method, for example:
namespace Your.Namespace
{
partial class YourDataContext
{
// your methods here
}
}
No; you can't add this to the get. Another alternative, though, is an extension method:
namespace Some.Utility.Namespace
{
public static class SomeUtilityClass
{
public static string ChangeSpecialCharacters(this string kund)
{ ... } // note the "this" in the above line
}
}
Now you can use:
string name = obj.Name.ChangeSpecialCharacters();
personally I would rename this to clarify the direction of the change, and have two methods - one to encode, one to decode.
Re doing this for a set of data; perhaps:
public static IEnumerable<SomeType> ChangeSpecialCharacters(
this IEnumerable<SomeType> items)
{
foreach(var item in items)
{
item.Name = item.Name.ChangeSpecialCharacters();
item.Foo = item.Foo.ChangeSpecialCharacters();
...
item.Bar = item.Bar.ChangeSpecialCharacters();
yield return item;
}
}
probably you could initialize your variable as:
private string kund;
public string Kund
{
get
{
return changeSpecialCharacters(string kund);
}
set
{
kund = value;
}
}

c# gettype of object from class

How could I make this work?:
public class myClass
{
public string first;
public int second;
public string third;
}
public string tester(object param)
{
//Catch the name of what was passed not the value and return it
}
//So:
myClass mC = new myClass();
mC.first = "ok";
mC.second = 12;
mC.third = "ko";
//then would return its type from definition :
tester(mC.first) // would return : "mc.first" or "myClass.first" or "first"
//and
tester(mC.second) // would return : "mc.second" or "myClass.second" or "second"
In the absence of infoof, the best you can do is Tester(() => mC.first) via expression trees...
using System;
using System.Linq.Expressions;
public static class Test
{
static void Main()
{
//So:
myClass mC = new myClass();
mC.first = "ok";
mC.second = 12;
mC.third = "ko";
//then would return its type from definition :
Tester(() => mC.first); // writes "mC.first = ok"
//and
Tester(() => mC.second); // writes "mC.second = 12"
}
static string GetName(Expression expr)
{
if (expr.NodeType == ExpressionType.MemberAccess)
{
var me = (MemberExpression)expr;
string name = me.Member.Name, subExpr = GetName(me.Expression);
return string.IsNullOrEmpty(subExpr)
? name : (subExpr + "." + name);
}
return "";
}
public static void Tester<TValue>(
Expression<Func<TValue>> selector)
{
TValue value = selector.Compile()();
string name = GetName(selector.Body);
Console.WriteLine(name + " = " + value);
}
}
This is not possible. Variable names don't exist in compiled code, so there's no way you can retrieve a variable name at runtime
That's not possible. "param" will have no information on where the value came from.
When calling tester(), a copy of the value in one of the properties is made, so the "link" to the property is lost.

Categories