c# Use of public static properties outside derived class - c#

I'm a beginner in C#. I want to do the following:
Having class A in namespace nA I need to implement class B in namespace nB that inherits everything from A and adds some functionality, that's fine.
In ProjectA I have:
namespace nA{
public abstract class A{
public const int a = 1;
}
}
in ProjectB t I have:
using ProjectA.nA;
namespace nB{
class abstract B : A{
public const int b = 2;
}
}
and in ProjectC I have
using ProjectB.nB;
namespace nC{
class C{
void someMethod(){
int valueA = B.a //error, nB.B does not contain a definition for 'a'
int valueB = B.b //works just fine
}
}
}

Since it should work, I would suggest that you check you're not missing any assembly references in your projects.

Constants and static members are always accessed via the class that actually defines thems. A.a will work. Also note that it is accessible from any class, not just an inheritor.

In project B write:
using ProjectA.nA;
namespace nB{
class abstract B : A{
public const int a = A.a;
public const int b = 2;
}
}
Then project C should compile. Or one could do:
using ProjectB.nB;
namespace nC{
class C{
void someMethod(){
int valueA = ProjectA.nA.a;
int valueB = B.b;
}
}
}
Since ProjectC will have to reference ProjectA.
The better lesson here is to think in terms of separation of concerns. If class C should not know directly about class A, then it should also not now about a constant class A defines. Instead, there should be some functionality in B which uses the constant and makes sense for what class B is attempting to accomplish. Hence, what class B is concerned with that uses class A and provides this appropriate separation.

Related

Can't get C# default interface method to compile

C# 8.0 has a new feature that lets you add a default implementation to a method on an interface. Either I'm doing something wrong or this feature doesn't work as advertised. (I'm guessing it's the former.)
I created a new .NET Core 3.1 console app with the following code:
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var xxx = new MyClass { MyInt = 5 };
Console.WriteLine(xxx.GetItNow());
}
}
public interface ITest
{
int MyInt { get; set; }
int GetItNow() => MyInt * 2;
}
public class MyClass : ITest
{
public int MyInt { get; set; }
}
}
The Console.WriteLine(xxx.GetItNow())); statement doesn't compile because
Myclass does not contain a definition for 'GetItNow()'...
So, the compiler is happy with the fact that MyClass doesn't explicitly reference GetItNow() (it doesn't complain the MyClass doesn't implement the interface). But it doesn't see the default interface member as a public method of the class that implements the interface.
Am I missing something, or is something broken?
Well, interface default method belongs to the interface not to a class which implements it; so you have two possibilities:
Cast:
Console.WriteLine(((ITest)xxx).GetItNow()));
Declaration change (preferable; MyClass is implementation detail, often it's a dependency; ITest - contract is the only thing which matter):
ITest xxx = new MyClass { MyInt = 5 };
// xxx is ITest, so xxx.GetItNow() is legal now
Console.WriteLine(xxx.GetItNow());
https://stackoverflow.com/a/61717913/779967 is excellent and clear answer, I was trying to do the same with this new feature but got stopped by the compiler. Now I know why.
If your intention is to mark some class with an interface and get some functionality attached to it. I’ve been using extension methods on the interface itself to achieve this effect. The only downside is that only functions are supported at this time not properties.
public interface ITest
{
int MyInt { get; set; }
}
public static class ITestExtensions
{
public static int GetItNow(this ITest self)
{
return self.MyInt * 2;
}
}

Need to add same properties in two different classes

I have two classes like Class A and Class B. Class A have some properties, methods and Class B have only the properties. But both Classes have the same set of properties.
My Question is, If I add any new property in Class A, I need to add that in Class B also. If I did not add means, need to show error. How can I achieve this through C#?
You may achieve this by using an Interface and implementing it both in class A and class B. In the interface, define the property that is required in class A and B:
public interface ICommonProperty
{
string MyProperty{ get; set; }
}
Or you can use keyword abstract to create a class in common for A and B.
abstract class BaseClass // Abstract class
{
public int X {get;set;} // property in common for 2 class
}
class A : BaseClass
{
}
class B : BaseClass
{
public int Y {get;set;} // other property of B
}
You can go with the abstract class. The abstract keyword enables you to create classes and class members that are incomplete and must be implemented in a derived class.
Here is a simple example related to your question However you can understand and learn about Abstract classes here : Abstract Class
using System;
public class Program
{
public static void Main()
{
A objA = new A();
objA.printA();
B objB = new B();
objB.printB();
}
}
abstract class Parent{
public int a = 5;
}
class A : Parent
{
public void printA()
{
Console.WriteLine("In class A, value is "+a);
}
}
class B : Parent
{
public void printB()
{
Console.WriteLine("In class B, value is "+a);
}
}
Output of the above program is:
In class A, vlaue is 5
In class B, vlaue is 5
Hope this helps you.

Complete nested partial class in child class

I have two classes, A and B. B inherits from A.
Here is my problem : I have a constant ConstantA which is useful for the class A, but also for the child classes. I also have a constant ConstantB, which is specific to my class B.
Since I store my constants in a public static nested class, the Constants class in the child class hides the parents one. I tried making it a partial class, it does not help. Is there any way to solve this?
Here's an example :
public class A
{
public static partial class Constants
{
public const int ConstantA = 1;
}
}
public class B : A
{
public static partial class Constants
{
public const int ConstantB = 1;
}
}
Thank you!
You would need to make A a partial class as well, and declare your B-specific constant separately from the B class itself:
public partial class A
{
public static partial class Constants
{
public const int ConstantA = 1;
}
}
public partial class A
{
public static partial class Constants
{
public const int ConstantB = 1;
}
}
public class B : A
{
static void M()
{
int i = Constants.ConstantB;
int j = Constants.ConstantA;
}
}
That said, I'm skeptical that design is all that good. It has the effect of declaring your ConstantB value inside A, which seems contrary to the goal of encapsulation, assuming ConstantB really is relevant only to class B. If you declare it this way, ConstantB is accessible via any use of the Constants class, in any type.
But if you're okay with that, and are just trying to make sure the declaration of the constant stays with the B class, then the above will work.
Other options include going ahead and hiding (using the new keyword) the base Constants class, with the minor inconvenience of having to specify the base class as fully-qualified to access the base values (e.g. A.Constants.ConstantA), hiding the base class and having the B.Constants class inherit A.Constants (requires abandoning the static class attribute) or, IMHO much better, not using a nested class at all, and instead putting the Constants classes in their respective namespaces.
Simply make your ConstantA an attribute of your parent class, putting this attribute in a nested class removes it from the scope of the inherited class.
If you really want nested classes, you can leave the static keyword, and do inheritance for the B.Constants nested class:
public class A
{
public class Constants
{
public const int ConstantA = 1;
}
}
public class B : A
{
public new class Constants : A.Constants
{
public const int ConstantB = 2;
}
}
The usage will be the same.

Downcast an inherited class to base class

Let say i have a base class
class baseClass
{ }
And another class that inherit from that baseClass
class foo : baseClass
{ }
I tryed to cast it back directly (baseClass)foo but the compiler say it cannot be done.
Is there a way from foo to get only the baseClass?
foo is a baseClass you don't need any casting. And your code should work without any problems:
var foo = new foo();
baseClass x = (baseClass) foo;
If you derive a class A from class B you can always refer to A as if it were B. Of course this is not true in the revese case. In general you can always refer down the chain of inherited classes.
If the compiler complain on such a thing, it could just mean you have several baseClass defined in several Namespace and you're actually not referencing the right baseClass.
Check your Namespaces it should solve your bug.
Here a working example with different Namespaces
namespace BaseNameSpace
{
public class BaseClass
{
public string Name { get; set; }
}
}
namespace TestNameSpace.Class
{
public class TestClass : BaseClass
{
public string Address { get; set; }
}
}
Use :
TestClass test1 = new TestClass();
BaseClass b = test1;
Ensure that there is the correct using :
using BaseNameSpace;
using TestNameSpace.Class;

Dynamically Compose a Class in C#

Is it possible to dynamically compose a class from the methods contained in other Classes?
For instance. Class A, B and C have public methods named such that they can be identified easily. They need to be extracted and added to Class D. Class D, which then contains all of the implementation logic can be passed further into a system which only accepts a single instance of Class D and dynamically binds these methods to other functions.
To be clear, this is not inheritance I'm looking for. I'm literally stating that methods with different names need to be stuffed into one class. The system I pass it into understands these naming conventions and dynamically binds them (it's a black box to me).
I am going down the path of extracting the methods from A, B, and C, dynamically combining them with the source of Class D in memory and compiling them into a new Class D and then creating an instance of D and passing it forward.
public class A{ public void EXPORT_A_DoSomething(){} }
public class B{ public void EXPORT_B_DoSomethingElse(){}}
public class C{ public void EXPORT_C_DoAnything(){}}
//should become
public class D{
public void EXPORT_A_DoSomething(){}
public void EXPORT_B_DoSomethingElse(){}
public void EXPORT_C_DoAnything(){}
}
Is there a way to extract the MethodInfos from class A, B and C and somehow directly attach them to Class D? If so how?
I would consider using the C# Class compiler. From what I can remember you can build code that is in a string and you can get an assembly as output. This then enables you to invoke methods through reflection.
There is an example on the MSDN link I have specified but I will mock one up for here once I find my project.
You won't be able to export just the methods. The methods can't really be separated from the class that they are in. (they need access to all of the member fields/properites including inherited).
I think the only thing you can do is emit a interface implementation. (even though you say it's not what you need, I don't see a way around needing the private state for those objects)
You can make a single interface which contains only the methods you need, and provide a class that supports it which contains an instance of each type of object.
public class A{ public void DoSomething(){} }
public class B{ public void DoSomethingElse(){}}
public class C{ public void DoAnything(){}}
public interface ID
{
void A_DoSomething();
void B_DoSomethingElse();
void C_DoAnything();
}
public class D : ID
{
private A a;
private B b;
private C c;
public D(A a,B b, C c) { this.a=a;this.b=b;this.c=c; }
public void A_DoSomething(){ a.DoSomething();}
public void B_DoSomethingElse(){ b.DoSomethingElse();}
public void C_DoAnything(){ c.DoSomething();
}
If you need to generate this dynamically, look into Reflection.Emit. It'll be some business about how you've got to create a new assembly, and then load it dynamically into the AppDomain. I'd try to avoid that if you can.
It should actually be possible using something called "Mixins" and proxy generators. Take a look at Castle.DynamicProxy's tutorial: Mixins
Another solution is to define the class get and set accessors for the function as an interface, and declare the functions you are interested in.
interface iA
{
public int a { get; set; }
}
interface iB
{
public int b { get; set; }
}
interface iAB : iA, iB
{
}
class MyClass : iA, iB
{
public int b { get; set; }
public int a { get; set; }
}
static class MyClassExtender
{
static public int Foo(this iAB ab)
{
int c = ab.a + ab.b;
ab.a = c;
return c;
}
static public int FooA(this iA a)
{
int c = ab.a + 1;
ab.a = c;
return c;
}
static public int FooB(this iB b)
{
int c = ab.b + 1;
ab.a = c;
return c;
}
}
So now "MyClass" can use Foo, FooA, and FooB as public methods.
Have you considered simply using a hash or list of delegates in you D class that point to the methods on the other classes? Alternatively, use a dynamic object (google ExpandoObject).

Categories

Resources