Different level of accessors for class and enum - c#

I need to keep my enumeration internal and I need to keep my class style public. How to handle in this situation?
public class Style : VisionItem, BaseItem
{
public string TargetType { get; set; }
public string FontFamily { get; set; }
public int FontSize { get; set; }
public StyleType Type { get; set; }
}
internal enum StyleType
{
TextCss,
TextJs
}
I received such error: Inconsistent accessibility: property type 'StyleType' is less accessible than property 'Style.Type'

The type Style can be public, but external code can't see the Type property. eg
public class Style : VisionItem, BaseItem
{
public string TargetType { get; set; }
public string FontFamily { get; set; }
public int FontSize { get; set; }
internal StyleType Type { get; set; }
}
internal enum StyleType
{
TextCss,
TextJs
}

You can declare enum like this:
internal enum StyleType : int {
TextCss,
TextJs
}
and Style with Type as int propety that set StyleType local variable
private StyleType type;
public int Type {
get => (int) type;
/*internal*/ set {
if(Enum.IsDefined(typeof(StyleType), value))
type = (StyleType) value;
else
throw new ArgumentOutOfRangeException();
}
}

Related

Set interface us a properties c#

I've created three interfaces - IUser, ICostCenter, IDepartment. IUser and IDepartment are properties of ICostCenter.
public interface ICostCenter
{
IDepartment Department { get; set; }
User.IUser CostCenterHead { get; set; }
}
The class implementing ICostCenter will be used in the DbContext for my db.
public class tblCostCenter : WorkingInterface.Interface.Organization.ICostCenter
{
public tblCostCenter()
{
this.ID = Guid.NewGuid().ToString();
}
public string ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
private WorkingInterface.Interface.User.IUser CostCenterHead { get; set; }
public string UserID { get; set; }
[ForeignKey("UserID")]
public Model.tblUser UserObject
{
get { return (Model.tblUser)this.CostCenterHead; }
set { this.CostCenterHead = value; }
}
private WorkingInterface.Interface.Organization.IDepartment Department { get; set; }
public string DepartmenID { get; set; }
[ForeignKey("DepartmenID")]
public Model.tblDepartment DepartmentObject
{
get { return (Model.tblDepartment)this.Department; }
set { this.Department = (Model.tblDepartment)value; }
}
}
I'm getting an error because I made the IUser and IDepartment properties private. How can I properly implement the interface? I want these properties to be hidden.
The interface is declared explicitly as public, that means that all the members declared in that interface MUST be public
So you need to declare both of these properties as public:
public WorkingInterface.Interface.User.IUser CostCenterHead { get; set; }
public WorkingInterface.Interface.Organization.IDepartment Department { get; set; }
NOTE: these have been declared as implicit implementations, so they are available to all contexts. If you want to hide them from general use, you can use explicit implementation.
Because you tried to use private accessibility, I assume you generally want to hide these properties from view, you can do this and still honor the interface contract by using explicit implementation syntax:
WorkingInterface.Interface.User.IUser ICostCenter.CostCenterHead { get; set; }
WorkingInterface.Interface.Organization.IDepartment ICostCenter.Department { get; set; }
They are still public but can only be accessed by first casting the object to the specific interface type explicitly.
tblCostCenter obj = new tblCostCenter();
...
// this wont work:
Console.WriteLine(obj.CostCenterHead);
// instead you will have to cast the object first
Console.WriteLine((obj as ICostCenter)).CostCenterHead);
// or if the local variable was an ICostCenter
ICostCenter costObj = obj;
Console.WriteLine(costObj.CostCenterHead);
...
// Pattern matching can also be helpful in these scenarios
if (obj is ICostCenter cc)
Console.WriteLine(cc.CostCenterHead);
If you want to use explicit declaration in your class you could try this:
WorkingInterface.Interface.User.IUser ICostCenter.CostCenterHead { get; set; }
public string UserID { get; set; }
[ForeignKey("UserID")]
public Model.tblUser UserObject
{
get { return ((ICostCenter)this).CostCenterHead as Model.tblUser; }
set { ((ICostCenter)this).CostCenterHead = value; }
}
WorkingInterface.Interface.Organization.IDepartment ICostCenter.Department { get; set; }
public string DepartmenID { get; set; }
[ForeignKey("DepartmenID")]
public Model.tblDepartment DepartmentObject
{
get { return ((ICostCenter)this).Department as Model.tblDepartment; }
set { ((ICostCenter)this).Department = value; }
}
this only works if:
Model.tblDepartment : IDepartment
Model.tblUser : User.IUser

How to serialize to XML generic classes?

I have these interfaces:
public interface IParameter
{
string Name { get; }
object UntypedValue { get; set; }
}
public interface IValidationPolicy<T>
{
bool Validate(T toValidate);
T Default();
}
A parameter base class
[Serializable]
public abstract class ParameterBase : IParameter
{
public abstract string Name { get; protected set; }
public abstract object UntypedValue { get; set; }
}
A parameter concrete class (I have more but them are quite similar):
public class Parameter<T, V> : ParameterBase where V : IValidationPolicy<T>
{
[XmlAttribute("Name")]
public override string Name { get; protected set; }
[XmlIgnore]
protected V validation_policy_;
[XmlElement("AnyValidation", Type = typeof(AnyValidation<>))]
[XmlElement("MultiOptionsValidation", Type = typeof(MultiOptionsValidation<>))]
[XmlElement("RangeValidation", Type = typeof(RangeValidation<>))]
[XmlElement("TextValidation", Type = typeof(TextValidation))]
public V Validation
{
get
{
return validation_policy_;
}
}
[XmlIgnore]
protected T value_;
[XmlElement("Value")]
public T Value
{
get
{
return value_;
}
set
{
if (validation_policy_.Validate(value))
{
value_ = value;
}
}
}
[XmlIgnore]
public object UntypedValue
{
get
{
return Value;
}
set
{
throw new NotImplementedException();
}
}
}
And an XMLParameter class:
public class XMLParameter : INotifyPropertyChanged
{
public string Description { get; set; }
public int PasswordLevel { get; set; }
public bool Enabled { get; set; }
public ParameterBase Parameter { get; set; }
}
How can I serialize and deserialize a list of XMLParameters?
In particular I have problem on serializing the IParameter objects.
Since the interface is not serializable as first attempt I created a base abstract class ParameterBase and derive the Parameter from it.
But when I try to serialize it in a test method:
var validation = new RangeValidation<int>() { MinValue = 1, MaxValue = 6 };
var parameter = new Parameter<int, RangeValidation<int>>();
parameter.Initialize("NumberOfTrays", validation);
parameter.Value = 6;
XElement par = validation.ToXElement<Parameter<int, RangeValidation<int>>>();
I got an exception: Error at reflection of type 'ConfigurableLibray.Parameter'2[System.Int32,ConfigurableLibray.RangeValidation'1[System.Int32]]'
The inner exception says that ConfigurableLibray.Parameter'2[T,V] is not supported
What am I doing wrong?
Thanks in advance for any suggestion!
I solved implementing manually the serialization and deserialization of the classes using reflection.

Inconsistent accessibility: field type 'System.Collections.Generic.Dictionary<> is less accessible than other field

[Serializable]
class LotInfo
{
public int ID { get; set; }
public string DonorName { get; set; }
public string BloodGroup { get; set; }
public string RhFactor { get; set; }
public string Address { get; set; }
public string TelephoneNumber { get; set; }
public LotInfo(int id)
{
ID = id;
}
public LotInfo()
{
}
}
[Serializable]
public class LotInfoDatabase
{
public Dictionary<int, LotInfo> dicLotDatabase = new Dictionary<int, LotInfo>();
public int LastID { get; set; }
public int GetNewID()
{
return (++LastID);
}
}
Guys, I am doing Serializer for datagridview for saving and loading the data. But this error comes...
Inconsistent accessibility: field type 'System.Collections.Generic.Dictionary' is less accessible than field 'Blood_Bank_Management.LotInfoDatabase.dicLotDatabase'
Im new to stackoverflow, please forgive me if I've did any wrong. Thanks...
LotInfo is an internal class, rather than public, because you've not specified any modifier for it.
But then you construct a type Dictionary<int, LotInfo> and try to expose it via a public field (dicLotDatabase) on a public type (LotInfoDatabase). Making LotInfo public would be one way to fix this problem, but I'm not sure if it's what you want to do.

Classes with the same interface but different types for a property

I would like to have this kind of design :
public interface IDifferentTypes
{
}
public class IntegerType : IDifferentTypes
{
public int value { get; set; }
}
public class StringType : IDifferentTypes
{
public string value { get; set; }
}
public class DateTimeType : IDifferentTypes
{
public DateTime value { get; set; }
}
but with the property 'value' defined in the interface.
So I can call something like that :
IDifferentTypes someInt = GetSomeInt(); // GetSomeInt() returns a IntegerType object
Assert.AreEqual(5, someInt.value);
IDifferentTypes someString = GetSomeString(); // GetSomeString() returns a StringType object
Assert.AreEqual("ok", someString.value);
Problem is that the type of value is different for each implementation, what is the best way to deal with that?
You could define a generic interface (but it will have to be a property, or, more strictly, it can't be a field):
public interface IHasValue<T> {
T Value { get; }
}
Where T is the type, a placeholder, if you will, and you can do:
public class HasStringValue : IHasValue<string> {
public string Value { get; private set; }
}
Use generics if you can:
var someInt = GetSomeInt();
Assert.AreEqual(5, someInt.Value);
var someString = GetSomeString();
Assert.AreEqual("ok", someString.Value);
// ...
public interface IDifferentTypes<T>
{
T Value { get; set; }
}
public class IntegerType : IDifferentTypes<int>
{
public int Value { get; set; }
}
public class StringType : IDifferentTypes<string>
{
public string Value { get; set; }
}
public class DateTimeType : IDifferentTypes<DateTime>
{
public DateTime Value { get; set; }
}
interface IDifferentTypes
{
Object Value { get; set; }
}
class StringType : IDifferentTypes
{
string _value;
public Object Value
{
get
{
return _value;
}
set
{
_value = value as string;
}
}
}
But this means that every time you use StringType.Value you're going to need to recast it. You may want to also expose a public accessor of the specific type. You also may want to add some protections against assigning the wrong type:
class StringType : IDifferentTypes
{
public String StringProperty { get; set; }
public Object Value
{
get
{
// works with any type that can auto cast to `Object`
return StringProperty;
}
set
{
// Optional
if( typeof(string) != value.GetType() )
{
throw new MyException();
}
// works for any nullable type
StringProperty = value as string;
// OR
// throws an exception if conversion fails
StringProperty = (string)value;
}
}
}

Hide enum values in derived class

I have the following
public enum MessageType
{
Warning,
Info,
Error
}
public class CalculationMessage
{
public string Message { get; set; }
public MessageType Type { get; set; }
}
public class ValidationMessage
{
public string Message { get; set; }
public MessageType Type { get; set; }
public string ErrorValue { get; set; }
}
I am trying to create a base class from which both of these classes are derived, however I have a problem with the enum as a ValidationMessage can be Error / Warning / Info but a CalculationMessage can only be Warning or Info.
How is this best achieved?
Thanks in advance.
You could add a parameter validation in the setter:
set
{
if(value == MessageType.Warning || value == MessageType.Info)
{
this.messageType = value;
}
else
{
throw new ArgumentOutOfRangeException();
}
}
This is, however, a violation of the Liskov Substitution Principle. Therefore be careful and think if there may be a way around (e.g. not making the setter public at all, but determing the MessageType internally).

Categories