[DataContract]
public class UniqueNamedItem
{
[DataMember]
int Id { public get; protected set; }
[DataMember]
string Name { public get; protected set; }
}
[KnownType(typeof(UniqueNamedItem))]
[DataContract]
public class BasicNode : UniqueNamedItem
{
[DataMember]
SortedList<string, BasicNode> Children { public get; private set; }
public void addChild(BasicNode bn)
{
this.Children.Add(bn.Name, bn);
}
}
Can you tell me why inside my addChild function the call to bn.Name is not valid even though the UniqueNamedItem.Name property has a public get accessor?
The default accessibility for members of classes is private.
So Id and Name are private.
You need to add the correct access modifiers (I added public, you may have meant protected):
[DataContract]
public class UniqueNamedItem
{
[DataMember]
public int Id { public get; protected set; }
[DataMember]
public string Name { public get; protected set; }
}
One good reason to always declare the accessibility you want.
The UniqueNamedItem.Name property itself is private; you need to explicitly mark the property as public.
The modifiers on accessors can only restrict access further, not increase it.
You need to declare your properties as public (see below). The default is private.
[DataContract]
public class UniqueNamedItem
{
[DataMember]
public int Id { public get; protected set; }
[DataMember]
public string Name { public get; protected set; }
}
You need to make your properties public:
[DataContract]
public class UniqueNamedItem
{
[DataMember]
public int Id { public get; protected set; }
[DataMember]
public string Name { public get; protected set; }
}
Your properties are not explicitly marked as public, thus C# automatically considers them to be private.
So:
[DataContract]
public class UniqueNamedItem
{
[DataMember]
int Id { public get; protected set; }
[DataMember]
public string Name { public get; protected set; }
}
The default access is private, because if you make something public when it should really be private, it won't stop any correct code from working, and it could be that way for years before you realise (and it's also a breaking change to then fix it).
If on the other hand you make something private when it should be public, something will stop working immediately, you go on stackoverflow, a bunch of people say it's private, you fix it, and all is well.
Hence it's a sensible default.
Related
There is the following class:
public class A
{
[Required]
public string property { get; set; }
}
and it's used by another class like:
public class B
{
public A prop { get; set; }
public A prop2 { get; set; }
}
in my scenario, B.prop.property should be required while B.prop2.property should not be [Required].
Is there a way to override prop2.property attribute to be not required? and it also should affect the record recorded in the Database?
if not what is the most recommended practice to deal with such issue?
No. There is no way to achieve what you're talking about. You can do so via inheritance. For example:
public class C : A
{
public new string property { get; set; }
}
Then:
public class B
{
public A prop { get; set; }
public C prop2 { get; set; }
}
In other words, the property must literally be a type where that property is not required. You can't just disable an attribute on a class instance at a whim.
I'm reading user input from different types of CSV files having a few common and a few different attributes. I have created a base class TestCaseData and derived classes as below:
public abstract class TestCaseData
{
public abstract string ID { get; set; }
public abstract string Name{ get; set; }
}
public class DerivedClassOne :TestCaseData
{
public override string ID { get; set; }
public override string Name{ get; set; }
pubic string DerivedOneProperty{ get; set; }
}
public class DerivedClassTwo :TestCaseData
{
public override string ID { get; set; }
public override string Name{ get; set; }
pubic string DerivedTwoProperty{ get; set; }
}
I am reading the CSV file and creating a list of derived classes and assigning to list of base class as below
List<TestCaseData> lstTestCaseData = MethodCallToReturnListOf_DerivedOneClassFromCSV();
As now I have lstTestCaseData I have to validate the user inputs also where I am unable to find a way to write a single method to validate user input of type DerivedOneProperty or DerivedTwoProperty as they have their own properties. Anyone can help me here?
I have method signature something like that
public string ValidateCompleteFile(List<TestCaseData> TestCaseInputList, out bool IsInputValid)
You could instead put an abstract validation method on the TestCaseData class and then let each class that inherits this class implement it how they need to.
public abstract class TestCaseData
{
public abstract string ID { get; set; }
public abstract string Name{ get; set; }
public abstract bool Validate();
}
And then call this method for each entry in the TestCaseInputList collection.
The answer regarding an abstract method is the best solution if you're committed to the code pattern you originally conceived of (i.e. calling a validation method on each object). But perhaps it would be better to validate each field in its setter:
public abstract class TestCaseData
{
private string id, name;
public abstract string ID { get; set; }
public abstract string Name{ get; set; }
}
public class DerivedClassOne : TestCaseData
{
public override string ID
{
get { return id; }
set
{
if ( ... ) throw new ArgumentException();
...
id = value;
}
}
...
}
This way an exception is thrown as soon as an invalid value is encountered. Imagine if you created a million of these objects before checking if each one was valid, only to find that the very first one was invalid. This solution avoids a situation like that by proactively validating as the properties are set.
This question already has answers here:
In C#, what is the difference between public, private, protected, and having no access modifier?
(19 answers)
Closed 8 years ago.
I have a simple inheritance situation as follows:
I expected to be able to set the properties in Class2 from Class1 but this is not the case. Is there a way to set access to the properties in Class 2 so they act like protected variables?
public abstract class Class2
{
public DateTime Added { get; private set; }
public int ID { get; private set; }
}
public class Class1 : Class2
{
public string ImageFilename { get; set; }
public string LinkText { get; set; }
}
You need to set them as protected, not private. This lets you access it from derived classes, but not external classes.
public abstract class Class2
{
protected DateTime Added { get; set; }
protected int ID { get; set; }
}
public class Class1 : Class2
{
public string ImageFilename { get; set; }
public string LinkText { get; set; }
public Class1()
{
//You can set the variables from inside Class 1.
base.Added = DateTime.Now();
base.ID = 1;
}
}
If you want the properties to still be exposed externally, but as readonly, you can set the individual setters are protected instead:
public abstract class Class2
{
public DateTime Added { get; protected set; }
public int ID { get; protected set; }
}
I have the following two classes:
abstract class LogItem {
public String payload { get; set; }
public String serverId { get; set; }
public DateTime timeRecieved { get; set; }
}
class MyLogItem : LogItem
{
//No I want this to have to have the members from the abstract class above, as if it where an interface?
}
So in other words I am wanting a type if interface that can have definitions or variables which all classes that implement it have to have, but they could add more if they required ?
The above example builds, even if i dono add the members from the abstract class.
edit
Forget what I've said before. These are attributes, not methods. For them to be accessible on derived classes, you make them protected or public. The difference is that public members are visible to the world, while protected ones are visible to the class and subclasses.
Any class derived from your LogItem may have other variables.
abstract class LogItem {
public String payload { get; set; }
public String serverId { get; set; }
public DateTime timeRecieved { get; set; }
}
class MyLogItem : LogItem
{
//No I want this to have to have the members from the abstract class above, as if it where an interface?
private void TestMethod(){
String test = payload;
}
}
check out this post for more information
Your MyLogItem class can reference any of the above members directly. They are accessible
You may declare an interface with those
public interface MyInterface {
public String payload { get; set; }
public String serverId { get; set; }
public DateTime timeRecieved { get; set; }
}
and your class
public class MyLogItem : MyInterface
{
String _payload;
public String payload { get{ return _payload; } set {_payload=value;} }
...
}
The abstract keyword can also be applied to methods, as described here.
Is it possible to assign an attribute on a property and use it in order to assign other attributes - doing so without using reflection?
The code:
public class CashierOut : BaseActivity
{
[Description("Flag indicates whether break to execution.")]
[DefaultValue(false)]
[MyCustomAttribute(ParameterGroups.Extended)]
public bool CancelExecution { get; set; }
[Description("Flag indicates whether allow exit before declation.")]
[DefaultValue(true)]
[MyCustomAttribute(ParameterGroups.Extended)]
[DisplayName("Exit before declaration?")]
public bool AllowExitBeforeDeclare { get; set; }
}
I would like to do something like this:
public class CashierOut : BaseActivity
{
[MyResourceCustom("CashierOut.CancelExecution")]
public bool CancelExecution { get; set; }
[MyResourceCustom("CashierOut.AllowExitBeforeDeclare")]
public bool AllowExitBeforeDeclare { get; set; }
}
public sealed class MyResourceCustom : Attribute
{
public string ResourcePath { get; private set; }
public ParameterGroupAttribute(string resourcePath)
{
ResourcePath = resourcePath;
// Get attributes attributes value from external resource using the path.
}
}
Attributes simply add meta data to the members they are defined on - by themselves they do nothing.
You will have to use reflection in order to produce some behaviour depending on the attribute values.
This is how all attributes work - some of the tooling is aware of some attributes (like the compiler and the ConditionalAttribute), but this is still done via reflection.
Look into Aspect Oriented Programming. You can use tools like postsharp to modify your code either at compile or runtime.
You could add a member to MyResourceCustom that wraps Description, DefaultValue, and MyCustomAttribute in an immutable instance (maybe even a static global, if it can be the same for everyone).
public class MyResourceCustom : Attribute {
public MyResourceCustomDescriptor Descriptor { get; private set; }
public MyResourceCustom(MyResourceCustomDescriptor descriptor)
: base() {
Descriptor = descriptor;
}
public class MyResourceCustomDescriptor {
public string Description { get; private set; }
public bool DefaultValue { get; private set; }
public ParameterGroups ParameterGroup { get; private set; }
public MyResourceCustomDescriptor(string path) {
// read from path
}
}
public class MyAdvancedResouceCustomDescriptor : MyResourceCustomDescriptor {
public string DisplayName { get; private set; }
// etc...
}
When you fetch the attribute you can get its Descriptor property and read the values.
As a sidenote, you should name it IsDefaultValue.