Illegal declaration of a property and a static function. why? - c#

Can somone explain why I get this error on this code?
Error 1 The type
'ConsoleApplication1.TestClass'
already contains a definition for
'IsThisOK'
class TestClass
{
public bool IsThisOK { get; set; }
public static bool IsThisOK(string str)
{
return true;
}
public static void Test()
{
TestClass c = new TestClass();
c.IsThisOK = IsThisOK("Hello");
}
}

You're trying to define a property and a method with the same name. While you can have multiple methods that override each other (with different argument lists), you cannot have a property and a method that share the same name

You've declared IsThisOK twice, at line 3 and line 5 (property and static function).
Try to imagine how could the compiler could figure out to which you are referring later on?

Because you cannot provide same name to a function and a Property.
You cannot overload function with property.
You can use it in this way:
class TestClass
{
public bool IsThisOK { get; set; }
public static bool isThisOK(string str)
{
return true;
}
public static void Test()
{
TestClass c = new TestClass();
c.IsThisOK = isThisOK("Hello");
}
}

As other pointed out, you cannot have a method and a property with the same name.
However, you can more or less work around this by using an extension method if you like:
static class TestClassExtension
{
public static bool IsThisOK(this TestClass, string str)
{
return true;
}
}
class TestClass
{
public bool IsThisOK { get; set; }
public static void Test()
{
TestClass c = new TestClass();
c.IsThisOK = this.IsThisOK("Hello");
}
}

Related

c# initialize static variable from different classes

What I have is:
public static class IDs {
public static string someID { get; set; }
static IDs() {
log.info(someID);
// use someID here
}
}
public class otherClass {
public void otherMethod(string sym) {
IDs.someID = sym;
}
}
and then using an instance of otherClass like this:
otherClassInstance.otherMethod("someStringSymbol");
I dont have any build errors, but log.info(someID); is printing null.
I was expecting it to be someStringSymbol.
This is because the static constructor is called automatically before the first instance is created or any static members are referenced..
This means that when an instance of otherClass invokes IDs.someID = sym; the first operation that gets executed is the static constructor, i.e. the code inside static IDs().
At this point the static variable has not yet been initialized, and you are basically executing log.info(null);.
After the static constructor completes, the variable is initialized, so you should be able to see its value inside otherMethod, after the first reference of IDs.
Given the OP's requirement:
I want to use the value passed in someID in a switch statement
The solution could be to simply execute a static method whenever a new value is set, with the help of explicit getters and setters:
public static class IDs
{
private static string _someID; // backing field
public static string SomeID
{
get { return _someID; }
set
{
_someID = value;
DoSomethingWithSomeID();
}
}
private static DoSomethingWithSomeID()
{
// Use SomeID here.
switch (IDs.SomeID)
{
...
}
}
}
public class OtherClass
{
public void OtherMethod(string sym)
{
// This will set a new value to the property
// and invoke DoSomethingWithSomeID.
IDs.SomeID = sym;
}
}
DoSomethingWithSomeID will be invoked every time someone sets a new value to SomeID.
I dont think what you are trying to do is suited to static classes. I would try the following
public class IDs{
public string someID{ get; set; }
public IDs(string someId){
this.someID = someId;
log.info(this.someID);
//use someID here
}
}
pulic class otherClass{
public otherMethod(string sym){
IDs id = new IDs(sym);
}
}
public class anotherClass{
//access instance of otherClass in wrp and call otherMethod()
wrp.otherMethod("someStringSymbol")
}

calling a variable from one class to another always becomes null

Below is the sample code
public class class1
{
public static void emp(string name)
{
.....
value = (value that is returned)
}
}
public class class2
{
public static void studen(string division)
{
...
}
}
This is how i want to use. class2.studen(value);
Here i need to pass the value that is returned from class1 to the string division of class2.
Any help would be appreciated.
Here function emp and studen are in different class files.
As hatchet mentioned, you're not getting a result from class1. There's a lot of info missing from your post but based on what I think you're trying to do, try like this:
public class class1
{
public static string value { get; set; } // use the proper type here if it's not a string
public static void emp(string name)
{
.....
this.value = (value that is returned)
}
}
public class class2
{
public static void studen(string division)
{
class1.emp("Hello");
string class2Var = class1.value; // class2Var will now be "Hello"
}
}

Cannot access public methods through dll

I've a function QMain() whose return type is object.
public class QMain
{
public object objQ(string str)
{
if (str.ToUpper() == "A")
{
clsA objA = new clsA();
return objA;
}
else if (str.ToUpper() == "B")
{
clsB objB = new clsB();
return objB;
}
else
return "";
}
}
Following is clsA:
public class clsA
{
public string strMessage { get; private set; }
public static string staticField;
public bool cantAccessThisFn(string str)
{...}
}
Both of the above classes are in same project which is a class library. I've created another console application wherein I've included the above project's dll. Now, I'm doing:
QMain obj=new QMain();
object A=obj.objQ("A");
I can get strMessage, staticField but not cantAccessThisFn. If I directly make an object of clsA, I'm able to get cantAccessThisFn. Is there any way to get access to this function from obj (object of class QMain)?
I get the following error:
'object' does not contain a definition for 'cantAccessThisFn' and no extension method 'cantAccessThisFn' accepting a first argument of
type 'object' could be found (are you missing a using directive or an
assembly reference?)
The problem is your objQ method returns an object. You haven't defined any (extension) methods on object, so cantAccessThisFn definitely can't be accessed.
What you should do is this: create an interface with all methods you want to share between the two classes, and don't return object, but return IYourInterfaceName. Then you can access those methods and properties defined on the interface.
Something like this:
public class clsA : IYourInterface
{
...
}
public interface IYourInterface
{
string strMessage { get; }
bool cantAccessThisFn(string str);
}
Then your method should look like:
public IYourInterface objQ(string str)
{ ... }
And your assignment like this:
IYourInterface a = obj.objQ("A");
Now it is valid to call:
a.cantAccessThisFn("z");
This is to help you understand! and not the recommended solution.
Marked Patricks answer up, as that is the more correct way...
but to achieve what you had you could do something like.
Also I applied the standard naming camel cases for the Classes, Properties and local variables.
This also allows for ClsA and ClsB to have completely different Method/Property names. Again I am not suggesting this as the way to do it but to rather help understand what its happening.
public class Program
{
static void Main()
{
QMain obj = new QMain();
object a = obj.objQ("A");
//FYI the below commended out is not possible...
//ClsA.staticField is but that is not the instance you created.
//------------
//a.staticField //<--- not possible
//------------
var someA = a as ClsA; //<--- attempts to cast it as ClsA
var someB = a as ClsB; //<--- attempts to cast it as ClsB
if (someA != null) //check if the cast was successful
{
var var1 = someA.StrMessage;
}
else if (someB != null)
{
//...
}
}
}
public class QMain
{
public object objQ(string str)
{
if (str.ToUpper() == "A")
{
ClsA objA = new ClsA();
return objA;
}
else if (str.ToUpper() == "B")
{
ClsB objB = new ClsB();
return objB;
}
else
return "";
}
}
public class ClsA
{
public string StrMessage { get; private set; }
public static string StaticField;
public bool CantAccessThisFn(string str)
{
return true;
}
}
public class ClsB
{
public string StrMessageMyC { get; private set; }
public static string StaticFieldMyC;
public bool CantAccessThisFnMyC(string str)
{
return true;
}
}

How to know the calling Class Name?

Is there a way know which class has called a function in another class.
Eg:
public class A
{
public static string Aa = "test";
public void test()
{
B.testB();
}
}
public class B
{
public static void testB()
{
string Bb = A.Aa;
}
}
In the above example, i know the class A function has called the function in class B. But if there are many classes which will call the function in class B and all of those classes will have variable Aa in common, so how can i read its value and assign it to Bb. So in simple
string Bb = CalledClassName.Aa;
You could use the CallerMemberNameAttribute that was added with .NET 4.5. This will only get you the member name though:
public void SomeMethod ()
{
OtherMethod();
}
public void OtherMethod ([CallerMemberName] string memberName = null)
{
Console.WriteLine(memberName);
}
The attribute will fill the optional parameter at compile time, so it will actually call OtherMethod("SomeMethod").
You could also use a combination of accessing the stack trace and using reflection to read the Aa property of the type of the calling method. Note that this accesses debugging information, and is very vulnerable to changes in your code. It also has a bad performance, so you should avoid it. But just to show you how to use it:
public static void testB()
{
StackTrace stackTrace = new StackTrace();
Type callingType = stackTrace.GetFrame(1).GetMethod().DeclaringType;
FieldInfo field = callingType.GetField("Aa", BindingFlags.Public | BindingFlags.Static);
string Bb = (string) field.GetValue(null);
Console.WriteLine(Bb);
}
Use an interface, pass that in:
public interface AaInterface {
public string GetAa();
}
public class A : AaInterface
{
public static string Aa = "test";
public GetAa() { return Aa; }
public void test()
{
B.testB(this);
}
}
public class B
{
public static void testB(AaInterface pAa)
{
string Bb = pAa.GetAa();
}
}
I guess you are looking for something different than you are asking.
You should pass the instance of A to your method. All calling methods should pass the instance based on an interface. In that interface you put the properties and methods you want to share. In that way you can call the 'same' method for every passed instance.
public interface ISomeInterface
{
string Aa {get;}
}
public class A : ISomeInterface
{
public string Aa {get { return "a"; } }
}
Then you can pass it to this method:
public static void testB(ISomeInterface something)
{
string Bb = something.Aa;
}
Note that in this case, Aa is not allowed to be static. You could wrap that static in an instance property though.
If i understood your question correctly then you can pass a reference to a class instance in method as parameter then use 'is' operator to check its type:
public class A
{
public static string Aa = "test";
public void test(object calledClass)
{
if(calledClass is B) Aa = calledClass.Bb;
}
}
When you call this static method from class B just put :
A.Test(this)
P.S.
This is just an example of logic that you can use to achieve what you want
I geuss you can do something like this:
public class A {
public void test() {
B.testB(this);
}
}
public class B {
public static void testB(object sender) {
String className = sender.GetType().Name;
}
}
//To call
A a = new A();
a.test();

Call one constructor from another

I have two constructors which feed values to readonly fields.
public class Sample
{
public Sample(string theIntAsString)
{
int i = int.Parse(theIntAsString);
_intField = i;
}
public Sample(int theInt) => _intField = theInt;
public int IntProperty => _intField;
private readonly int _intField;
}
One constructor receives the values directly, and the other does some calculation and obtains the values, then sets the fields.
Now here's the catch:
I don't want to duplicate the
setting code. In this case, just one
field is set but of course there may
well be more than one.
To make the fields readonly, I need
to set them from the constructor, so
I can't "extract" the shared code to
a utility function.
I don't know how to call one
constructor from another.
Any ideas?
Like this:
public Sample(string str) : this(int.Parse(str)) { }
If what you want can't be achieved satisfactorily without having the initialization in its own method (e.g. because you want to do too much before the initialization code, or wrap it in a try-finally, or whatever) you can have any or all constructors pass the readonly variables by reference to an initialization routine, which will then be able to manipulate them at will.
public class Sample
{
private readonly int _intField;
public int IntProperty => _intField;
private void setupStuff(ref int intField, int newValue) => intField = newValue;
public Sample(string theIntAsString)
{
int i = int.Parse(theIntAsString);
setupStuff(ref _intField,i);
}
public Sample(int theInt) => setupStuff(ref _intField, theInt);
}
Before the body of the constructor, use either:
: base (parameters)
: this (parameters)
Example:
public class People: User
{
public People (int EmpID) : base (EmpID)
{
// Add more statements here.
}
}
I am improving upon supercat's answer. I guess the following can also be done:
class Sample
{
private readonly int _intField;
public int IntProperty
{
get { return _intField; }
}
void setupStuff(ref int intField, int newValue)
{
//Do some stuff here based upon the necessary initialized variables.
intField = newValue;
}
public Sample(string theIntAsString, bool? doStuff = true)
{
//Initialization of some necessary variables.
//==========================================
int i = int.Parse(theIntAsString);
// ................
// .......................
//==========================================
if (!doStuff.HasValue || doStuff.Value == true)
setupStuff(ref _intField,i);
}
public Sample(int theInt): this(theInt, false) //"false" param to avoid setupStuff() being called two times
{
setupStuff(ref _intField, theInt);
}
}
Here is an example that calls another constructor, then checks on the property it has set.
public SomeClass(int i)
{
I = i;
}
public SomeClass(SomeOtherClass soc)
: this(soc.J)
{
if (I==0)
{
I = DoSomethingHere();
}
}
Yeah, you can call other method before of the call base or this!
public class MyException : Exception
{
public MyException(int number) : base(ConvertToString(number))
{
}
private static string ConvertToString(int number)
{
return number.toString()
}
}
Constructor chaining i.e you can use "Base" for Is a relationship and "This" you can use for same class, when you want call multiple Constructor in single call.
class BaseClass
{
public BaseClass():this(10)
{
}
public BaseClass(int val)
{
}
}
class Program
{
static void Main(string[] args)
{
new BaseClass();
ReadLine();
}
}
When you inherit a class from a base class, you can invoke the base class constructor by instantiating the derived class
class sample
{
public int x;
public sample(int value)
{
x = value;
}
}
class der : sample
{
public int a;
public int b;
public der(int value1,int value2) : base(50)
{
a = value1;
b = value2;
}
}
class run
{
public static void Main(string[] args)
{
der obj = new der(10,20);
System.Console.WriteLine(obj.x);
System.Console.WriteLine(obj.a);
System.Console.WriteLine(obj.b);
}
}
Output of the sample program is
50 10 20
You can also use this keyword to invoke a constructor from another constructor
class sample
{
public int x;
public sample(int value)
{
x = value;
}
public sample(sample obj) : this(obj.x)
{
}
}
class run
{
public static void Main(string[] args)
{
sample s = new sample(20);
sample ss = new sample(s);
System.Console.WriteLine(ss.x);
}
}
The output of this sample program is
20
Error handling and making your code reusable is key. I added string to int validation and it is possible to add other types if needed. Solving this problem with a more reusable solution could be this:
public class Sample
{
public Sample(object inputToInt)
{
_intField = objectToInt(inputToInt);
}
public int IntProperty => _intField;
private readonly int _intField;
}
public static int objectToInt(object inputToInt)
{
switch (inputToInt)
{
case int inputInt:
return inputInt;
break;
case string inputString:
if (!int.TryParse(inputString, out int parsedInt))
{
throw new InvalidParameterException($"The input {inputString} could not be parsed to int");
}
return parsedInt;
default:
throw new InvalidParameterException($"Constructor do not support {inputToInt.GetType().Name}");
break;
}
}
Please, please, and pretty please do not try this at home, or work, or anywhere really.
This is a way solve to a very very specific problem, and I hope you will not have that.
I'm posting this since it is technically an answer, and another perspective to look at it.
I repeat, do not use it under any condition. Code is to run with LINQPad.
void Main()
{
(new A(1)).Dump();
(new B(2, -1)).Dump();
var b2 = new B(2, -1);
b2.Increment();
b2.Dump();
}
class A
{
public readonly int I = 0;
public A(int i)
{
I = i;
}
}
class B: A
{
public int J;
public B(int i, int j): base(i)
{
J = j;
}
public B(int i, bool wtf): base(i)
{
}
public void Increment()
{
int i = I + 1;
var t = typeof(B).BaseType;
var ctor = t.GetConstructors().First();
ctor.Invoke(this, new object[] { i });
}
}
Since constructor is a method, you can call it with reflection. Now you either think with portals, or visualize a picture of a can of worms. sorry about this.
In my case, I had a main constructor that used an OracleDataReader as an argument, but I wanted to use different query to create the instance:
I had this code:
public Subscriber(OracleDataReader contractReader)
{
this.contract = Convert.ToString(contractReader["contract"]);
this.customerGroup = Convert.ToString(contractReader["customerGroup"]);
this.subGroup = Convert.ToString(contractReader["customerSubGroup"]);
this.pricingPlan= Convert.ToString(contractReader["pricingPlan"]);
this.items = new Dictionary<string, Member>();
this.status = 0;
}
So I created the following constructor:
public Subscriber(string contract, string customerGroup) : this(getSubReader(contract, customerGroup))
{ }
and this method:
private static OracleDataReader getSubReader(string contract, string customerGroup)
{
cmdSubscriber.Parameters[":contract"].Value = contract + "%";
cmdSubscriber.Parameters[":customerGroup"].Value = customerGroup+ "%";
return cmdSubscriber.ExecuteReader();
}
notes: a statically defined cmdSubscriber is defined elsewhere in the code; My main constructor has been simplified for this illustration.
In case you need to run something before calling another constructor not after.
public class Sample
{
static int preprocess(string theIntAsString)
{
return preprocess(int.Parse(theIntAsString));
}
static int preprocess(int theIntNeedRounding)
{
return theIntNeedRounding/100;
}
public Sample(string theIntAsString)
{
_intField = preprocess(theIntAsString)
}
public Sample(int theIntNeedRounding)
{
_intField = preprocess(theIntNeedRounding)
}
public int IntProperty => _intField;
private readonly int _intField;
}
And ValueTuple can be very helpful if you need to set more than one field.
NOTE: most of the solutions above does not work for structs.
Unfortunately initializing struct fields in a method called by a constructor is not recognized by the compiler and will lead to 2 errors:
in the constructor: Field xxxx must be fully assigned...
in the method, if you have readonly fields: a read-only field cannot be assigned except in a constructor.
These can be really frustrating for example when you just need to do simple check to decide on which constructor to orient your call to.

Categories

Resources