I've searched extensively (though might have missed it). I've been doing so much web development that I can't seem to get this. I have a base case:
public class myfields
{
public String myfield1 { get; set; }
}
Then another class using this class:
class mydohere : myfields
{
public Boolean getValue {string xyz)
{
string abc = myfield1;
}
}
What I can't get it is, if I create:
mydohere Objmydohere = new mydohere();
The value of myfield1 is now null! All the values in base myfields are set to null (or empty since it is a new object). What is the best way to create fields (or parameters) in one class and share it among others without resetting their values? I've tried using keyword 'base'. I've tried using props and fields *since you can't instantiate them).
My goal is to to have a class of settable fields that I can use accross classes without making that class new for each class that is using it. Does this make sense? I'm sure there is a much better way to do this :)
It sounds like what you're looking for is a constant or static variable.
Use constant if it will always be the same:
const string myfield1 = "my const";
Use static if you'd like to set it once, maybe after doing some logic:
static string myfield1 = "my static";
This really depends on what you want to do with this "shared data" One way is to use a static class and dependency injection:
public interface Imyfields
{
String myfield1 { get; set; }
}
public class myfields : Imyfields
{
private static readonly Imyfields instance = new myfields();
private myfields()
{
}
public static Imyfields Instance
{
get
{
return instance;
}
}
public String myfield1 { get; set; }
}
class mydohere
{
private readonly Imyfields myfields;
public mydohere(Imyfields myfields)
{
this.myfields = myfields;
}
public Boolean getValue(string xyz)
{
string abc = this.myfields.myfield1;
}
}
Nothing is reset to null, it's never initialized with a value in the first time. In your base object, you only have a getter/setter, you don't have any code that initialize the value itself.
Maybe I don't understand the question well and others suggestion with static are what you really need! :)
Related
I have a configuration class store application configuration. Currently I am using a static class. Some of the configurations are related to one topic so I want to organize them into a nested class, so I can reference configurations like this:
AppConfig.Url
AppConfig.LogSettings.FileSize
I have two options, either use a static nested class,
public static class AppConfig
{
public static class LogSettings
{
public static int FileSize {get; set;}
}
}
or declare a class but add a static property:
public static class AppConfig
{
public class LogSettings
{
public int FileSize {get; set;}
}
public static LogSettings logSettings { get; private set; }
}
However, none of them can protect nested class member FileSize being modified by other classes, even I use private set to protect the public static property.
Maybe I should not use nested class to implement this? Any suggestions?
The other solutions given so far essentially require the property being set to be set once. I am very much in favour of immutable objects, but they are not always practical; is it possible to solve your problem and make the property mutable?
This is in fact a special case of the more general problem you pose: how can we mark certain members of an inner class as being accessible only to the outer class, but not to anything outside of that class?
It is by no means obvious how to do so, but this is surprisingly easy. The key to the solution is to remember that interfaces may be private implementation details. C# requires that a base class be at least as accessible as the class deriving from it, but C# does not require that an implemented interface be as accessible as the class implementing it!
using System;
public static class Outer
{
private interface IPrivates
{
string Name { set; }
}
public readonly static Inner TheInner = new Inner();
private readonly static IPrivates TheInnerPrivates = TheInner;
public class Inner : IPrivates
{
public string Name { get; private set; }
string IPrivates.Name { set { this.Name = value; } }
}
public static void DoIt()
{
TheInnerPrivates.Name = "abc";
}
}
public class Program
{
public static void Main()
{
Outer.DoIt();
Console.WriteLine(Outer.TheInner.Name);
}
}
Code inside of Outer may access the private members of Inner via the interface. Code outside of Outer cannot see anything other than the public members of Inner, because the interface they need to see the private members is itself private.
I voted for Eric's answer but wanted to put this here as 'something to consider'.
public class Tester
{
public Tester()
{
AppConfig.LogSettings.FileSize = 5; // compile error
Console.WriteLine(AppConfig.LogSettings.FileSize); // works
}
}
public static class AppConfig
{
// just an example of setting the value in the outer class
private static void SetFileSize(int size)
{
fileSize = size; // internal only setting works
}
private static int fileSize; // a member of AppConfig still
public static class LogSettings
{
public static int FileSize
{
get { return fileSize; } // internal classes can access private members of the outer class
}
}
}
When you access AppConfig externally you get the grouping you desire, however inside the AppConfig class the 'grouping' is simply about publicly exposing the getter, the actual member variable still belongs to AppConfig.
This works because the internal class can access private members of the outer class.
So if your grouping goal is mostly about the public interface - how you get the values - this approach is simpler, but if your goal is also have the grouping internally too...then obviously it doesn't deliver.
One option is to use a constructor of nested class to initialize values. For example:
public static class AppConfig {
static AppConfig() {
Log = new LogSettings(1);
}
public class LogSettings {
public LogSettings(int fileSize) {
FileSize = fileSize;
}
public int FileSize { get; private set; }
}
public static LogSettings Log { get; private set; }
}
Then other classes can create instance of LogSettings still, but cannot modify your instance.
If this is the approach you want to go with, I see 2 options:
You extract all the logic surrounding loading and parsing of the config file into a separate project (library), than you can mark your setters internal and other libraries won't be able to access them anymore.
You can implement a more explicit property which doesn't allow to set a value twice like:
private int? _fileSize;
public int FileSize {
get { return _fileSize ?? 0; }
set {
if (_fileSize.HasValue) {
throw new InvalidOperationException("You can only set the value once");
}
_fileSize = value;
}
}
Another option, which I've often used, is to encapsulate the parsing of different parts of a configuration to the sub classes. You provide that information in the constructor and the class initializes itself. (just like Evk commented in the meanwhile)
This question might look very simple for many, but I really want to understand the following
Difference between the two classes along with the Name property
Benefits of using one among the two
When & Where to use such (any practical applications)?
Code:
public class test1
{
public test1()
{
}
public string Name { get; set; }
}
public class test2
{
public test2(string name)
{
Name = name;
}
public string Name { get; set; }
}
public class SampleTest
{
public void PerformTests()
{
test1 Test1 = new test1();
Test1.Name = "Power Measurements";
test2 Test2 = new test2("Power Measurements");
}
}
to be more precise please consider the objects Test1 & Test2.
any help on this would be much appreciated.
The physical difference between the two classes is only in the constructor. One has a parameter; one doesn't.
The semantic difference is that test2 requires a Name. In test1, it is optional. So you would use test2 if you want to force a caller to provide a name.
Constructors with parameters force the developer to supply any required variables when creating and instance of the object.
For example, lets say each object should have a 'Name' but it cant be changed after the object is created.
public class TestClass
{
private string _name = string.Empty;
public string Name
{
get{ return _name; }
private set { _name = value; }
}
public TestClass(string name)
{
this.Name = name;
}
}
The constructor with no parameters is default, you can use it to create an object without any further specification, using a parameter you can specify a name or something else during the creation of the object. You should probably read more about the basics of object oriented programming to get a better understanding.
When your property is ment to be read-writable there might be no difference on both. It depends on if it is required property or optional one. When you define a constructor you force the property to be provided. In the other case your property might or might not be set by the user of your class. You may however provide a default-value for it within your constructor in this case.
However often you won´t need to have a writable property thus you can make it read-only (by declaring a private setter e.g.) and set its value within the constructor. In this case you have to provide the value within the constructors parameter.
public class TestClass
{
public string Name { get; private set; }
public TestClass(string name)
{
this.Name = name;
}
}
Now you may set the value of the property by providing it within the constructor. Once it has been set it is immutable (at least outside the scope of the class). However you may change the value inside the class. If you want to avoid this also you have to provide a readonly-backing-field for the property.
public class TestClass
{
private readonly _name;
public string Name { get { return this._name; } }
public TestClass(string name)
{
this._name = name;
}
}
This is the safest appraoch to avoid that the value you initlally provided within the constructor is ever changed either by a user of your class or within the class itself.
I have a series of objects, lets call them buildings, that each share certain properties that are static for that building, but different for each building, such as price. I assumed that the best way to implement this was to create an abstract superclass with the shared price attribute and set the values in each subclass, but I cannot figure out how to get this to work. Here is an example of something I have tried:
using System;
public abstract class Buildings
{
internal static int price;
internal static int turnsToMake;
}
using System;
public class Walls : Buildings
{
public Walls()
{
price = 200;
turnsToMake = 5;
}
}
This works fine for construction, but if I want to check the price before creating it (to check if the player has enough money) then it just returns a null value. I'm sure that it is is a super simple fix, but I can't figure it out. Any help?
There is a "patchy" yet simple solution that's worth to consider. If you define your base class as a Generic class, and in deriving classes set T as the class itself, It will work.
This happens because .NET statically defines a new type for each new definition.
For example:
class Base<T>
{
public static int Counter { get; set; }
public Base()
{
}
}
class DerivedA : Base<DerivedA>
{
public DerivedA()
{
}
}
class DerivedB : Base<DerivedB>
{
public DerivedB()
{
}
}
class Program
{
static void Main(string[] args)
{
DerivedA.Counter = 4;
DerivedB.Counter = 7;
Console.WriteLine(DerivedA.Counter.ToString()); // Prints 4
Console.WriteLine(DerivedB.Counter.ToString()); // Prints 7
Console.ReadLine();
}
}
Don't use static. Static says that all instances of Building have the same value. A derived class will not inherit its own copy of the statics; but would always modify the base class statics. In your design there would only be one value for price and turnsToMake.
This should work for you:
public abstract class Buildings
{
internal int price;
internal int turnsToMake;
}
However, most people don't like using fields these days and prefer properties.
public abstract class Buildings
{
internal int Price { get; set; }
internal int TurnsToMake { get; set; }
}
I want to check the price before creating it […]
I suppose that's how you got to static fields; however, static and virtual behaviour cannot be combined. That is, you would have to re-declare your static fields for each subclass. Otherwise, all your subclasses share the exact same fields and overwrite each others' values.
Another solution would be to use the Lazy<T, TMetadata> type from the .NET (4 or higher) framework class library:
public class Cost
{
public int Price { get; set; }
public int TurnsToMake { get; set; }
}
var lazyBuildings = new Lazy<Buildings, Cost>(
valueFactory: () => new Walls(),
metadata: new Cost { Price = 200, TurnsToMake = 5 });
if (lazyBuildings.Metadata.Price < …)
{
var buildings = lazyBuildings.Value;
}
That is, the metadata (.Metadata) now resides outside of the actual types (Buildings, Walls) and can be used to decide whether you actually want to build an instance ( .Value) of it.
(Thanks to polymorphism, you can have a whole collection of such "lazy factories" and find a building type to instantiate based on the metadata of each factory.)
Building on Uri Abramson's answer above:
If you need to access the static property from within the Base class, use reflection to get the value from T. Also, you can enforce that Base must be inherited using T of the derived type.
e.g.
class Base<T> where T : Base <T> {
static int GetPropertyValueFromDerivedClass<PropertyType>(BindingFlags Flags = BindingFlags.Public | BindingFlags.Static, [CallerMemberName] string PropertyName = "")
{
return typeof(T).GetProperty(PropertyName, Flags)?.GetValue(null);
}
static int Counter{ get => GetPropertyValueFromDerivedClass(); }
}
static int DoubleCounter{ return Counter*2; } //returns 8 for DerivedA and 14 for DerivedB
}
If you have a better way to do this, please post.
Not as easy for the inheritor, but workable...
public abstract class BaseType
{
public abstract contentType Data { get; set; }
}
public class InheritedType : BaseType
{
protected static contentType _inheritedTypeContent;
public override contentType Data { get => _inheritedTypeContent; set => _inheritedTypeContent = value; }
}
So I am having some issues with this. I am kinda new to C#. All my attributes are private and I am using the traditional get and set. It is an abstract class. But in the child class when I try and use it in another method, the compiler says cannot use as a method. However if I do the C++ way of accesors and mutators it works fine. Is there a way around this?
Thanks very much for your help
Never mind I got it. I have just been coding for like 7 hrs straight to get this assignment done for school and my brain isn't working right lol thanks very much though
This would be the standard C# way of doing what (I think) you're asking.
public abstract class Base
{
// Automatic Property
public string Prop1 { get; set; }
// With backing field
private string prop2;
public string Prop2
{
get { return prop2; }
set { prop2 = value; }
}
}
public class Derived : Base
{
public string Prop3 { get; set; }
}
public class AnotherClass
{
void Foo()
{
var derived = new Derived();
// Can get and set all properties
derived.Prop1 = derived.Prop1;
derived.Prop2 = derived.Prop2;
derived.Prop3 = derived.Prop3;
}
}
Is it possible to specify that members of a nested class can be accessed by the enclosing class, but not other classes ?
Here's an illustration of the problem (of course my actual code is a bit more complex...) :
public class Journal
{
public class JournalEntry
{
public JournalEntry(object value)
{
this.Timestamp = DateTime.Now;
this.Value = value;
}
public DateTime Timestamp { get; private set; }
public object Value { get; private set; }
}
// ...
}
I would like to prevent client code from creating instances of JournalEntry, but Journal must be able to create them. If I make the constructor public, anyone can create instances... but if I make it private, Journal won't be able to !
Note that the JournalEntry class must be public, because I want to be able to expose existing entries to client code.
Any suggestion would be appreciated !
UPDATE: Thanks everyone for your input, I eventually went for the public IJournalEntry interface, implemented by a private JournalEntry class (despite the last requirement in my question...)
Actually there is a complete and simple solution to this problem that doesn't involve modifying the client code or creating an interface.
This solution is actually faster than the interface-based solution for most cases, and easier to code.
public class Journal
{
private static Func<object, JournalEntry> _newJournalEntry;
public class JournalEntry
{
static JournalEntry()
{
_newJournalEntry = value => new JournalEntry(value);
}
private JournalEntry(object value)
{
...
If your class is not too complex, you could either use an interface which is publicly visible and make the actual implementing class private, or you could make a protected constructor for the JornalEntry class and have a private class JornalEntryInstance derived from JornalEntry with a public constructor which is actually instantiated by your Journal.
public class Journal
{
public class JournalEntry
{
protected JournalEntry(object value)
{
this.Timestamp = DateTime.Now;
this.Value = value;
}
public DateTime Timestamp { get; private set; }
public object Value { get; private set; }
}
private class JournalEntryInstance: JournalEntry
{
public JournalEntryInstance(object value): base(value)
{ }
}
JournalEntry CreateEntry(object value)
{
return new JournalEntryInstance(value);
}
}
If your actual class is too complex to do either of that and you can get away with the constructor being not completely invisible, you can make the constructor internal so it is only visible in the assembly.
If that too is infeasible, you can always make the constructor private and use reflection to call it from your journal class:
typeof(object).GetConstructor(new Type[] { }).Invoke(new Object[] { value });
Now that I think about it, another possibility would use a private delegate in the containing class which is set from the inner class
public class Journal
{
private static Func<object, JournalEntry> EntryFactory;
public class JournalEntry
{
internal static void Initialize()
{
Journal.EntryFactory = CreateEntry;
}
private static JournalEntry CreateEntry(object value)
{
return new JournalEntry(value);
}
private JournalEntry(object value)
{
this.Timestamp = DateTime.Now;
this.Value = value;
}
public DateTime Timestamp { get; private set; }
public object Value { get; private set; }
}
static Journal()
{
JournalEntry.Initialize();
}
static JournalEntry CreateEntry(object value)
{
return EntryFactory(value);
}
}
This should give you your desired visibility levels without needing to resort on slow reflection or introducing additional classes / interfaces
Make JournalEntry a private nested type. Any public members will be visible only to the enclosing type.
public class Journal
{
private class JournalEntry
{
}
}
If you need to make JournalEntry objects available to other classes, expose them via a public interface:
public interface IJournalEntry
{
}
public class Journal
{
public IEnumerable<IJournalEntry> Entries
{
get { ... }
}
private class JournalEntry : IJournalEntry
{
}
}
A simpler approach is to just use an internal constructor, but make the caller prove who they are by supplying a reference that only the legitimate caller could know (we don't need to be concerned about non-public reflection, because if the caller has access to non-public reflection then we've already lost the fight - they can access a private constructor directly); for example:
class Outer {
// don't pass this reference outside of Outer
private static readonly object token = new object();
public sealed class Inner {
// .ctor demands proof of who the caller is
internal Inner(object token) {
if (token != Outer.token) {
throw new InvalidOperationException(
"Seriously, don't do that! Or I'll tell!");
}
// ...
}
}
// the outer-class is allowed to create instances...
private static Inner Create() {
return new Inner(token);
}
}
In this case you could either:
Make the constructor internal - this stops those outside this assembly creating new instances or...
Refactor the JournalEntry class to use a public interface and make the actual JournalEntry class private or internal. The interface can then be exposed for collections while the actual implementation is hidden.
I mentioned internal as a valid modifier above however depending on your requirements, private may be the better suited alternative.
Edit: Sorry I mentioned private constructor but you've already dealt with this point in your question. My apologies for not reading it correctly!
For generic nested class =)
I know this is an old question and it has already an accepted answer, nevertheless for those google swimmers who may have a similar scenario to mine this answer may provide some help.
I came across this question for I needed to implement the same feature as the OP. For my first scenario this and this answers worked just fine. Nevertheless I needed also to expose a nested generic class. The problem is that you can not expose a delegate type field (the factory field) with opened generic parameters without making your own class generic, but obviously this is not what we want, so, here is my solution for such scenario:
public class Foo
{
private static readonly Dictionary<Type, dynamic> _factories = new Dictionary<Type, dynamic>();
private static void AddFactory<T>(Func<Boo<T>> factory)
=> _factories[typeof(T)] = factory;
public void TestMeDude<T>()
{
if (!_factories.TryGetValue(typeof(T), out var factory))
{
Console.WriteLine("Creating factory");
RuntimeHelpers.RunClassConstructor(typeof(Boo<T>).TypeHandle);
factory = _factories[typeof(T)];
}
else
{
Console.WriteLine("Factory previously created");
}
var boo = (Boo<T>)factory();
boo.ToBeSure();
}
public class Boo<T>
{
static Boo() => AddFactory(() => new Boo<T>());
private Boo() { }
public void ToBeSure() => Console.WriteLine(typeof(T).Name);
}
}
We have Boo as our internal nested class with a private constructor and we mantain on our parent class a dictionary with these generic factories taking advantage of dynamic. So, each time TestMeDude is called, Foo searches for whether the factory for T has already been created, if not it creates it calling nested class' static constructor.
Testing:
private static void Main()
{
var foo = new Foo();
foo.TestMeDude<string>();
foo.TestMeDude<int>();
foo.TestMeDude<Foo>();
foo.TestMeDude<string>();
Console.ReadLine();
}
The output is:
The solution Grizzly suggested does make it a bit hard to create the nested class somewhere else but not impossible,like Tim Pohlmann wrote someone can still inherit it and use the inheriting class ctor.
I'm taking advantage of the fact that nested class can access the container private properties, so the container asks nicely and the nested class gives access to the ctor.
public class AllowedToEmailFunc
{
private static Func<long, EmailPermit> CreatePermit;
public class EmailPermit
{
public static void AllowIssuingPermits()
{
IssuegPermit = (long userId) =>
{
return new EmailPermit(userId);
};
}
public readonly long UserId;
private EmailPermit(long userId)
{
UserId = userId;
}
}
static AllowedToEmailFunc()
{
EmailPermit.AllowIssuingPermits();
}
public static bool AllowedToEmail(UserAndConf user)
{
var canEmail = true; /// code checking if we can email the user
if (canEmail)
{
return IssuegPermit(user.UserId);
}
else
{
return null
}
}
}
This solution is not something I would do on a regular day on the job, not because it will lead to problems in other places but because it's unconventional (I've never seen it before) so it might cause other developers pain .