i have an object which have an attribute of Serializable, this class inherit from abstract class which inherit from other class which also Serializable which inherit from an interface
i have used
string included = JsonConvert.SerializeObject(msg,
Formatting.Indented,
new JsonSerializerSettings { /*ContractResolver = new NotificationPropertyResolver()*/ TypeNameHandling = TypeNameHandling.All});
as msg is the interface
I want to send this object in SignalR and i see that it dont ignore any member,
i have decorated the interface and the classes
is there solution for that?
i have tried also to use resolver with my own attributes - but still same results
the classes are to big but ...
[Serializable]
[WebAPINotification(Type = typeof(CSensor), Group = "Sensor")]
public class SensorsStateModeNotification : SensorNotification, IBPMPackagedNotification
public abstract class SensorNotification : BasicLanNotification, ISensNotification
[Serializable]
public class BasicLanNotification : BasicNotification, ILanNotification
[Serializable]
public abstract class BasicNotification : INotification, ISerializable, IOpSerializable
[JsonIgnore]
public long SentAt
{
get
{
return m_sentAt;
}
set
{
m_sentAt = value;
}
}
/// <summary>
///
/// </summary>
[JsonIgnore]
public ENotificationGateway NotificationGateway
{
get
{
return m_NotifyGateway;
}
set
{
m_NotifyGateway = value;
}
}
Your type implements the ISerializable interface - that takes precedence over attributes. If you don't want to serialize the members of the class, simply don't return them in the ISerializable.GetObjectData implementation. See the SSCCE below (and by the way, in the future if you want better answers, you should provide one as well) for an example.
public class StackOverflow_18127665
{
public class WebAPINotificationAttribute : Attribute
{
public Type Type { get; set; }
public string Group { get; set; }
}
public class CSensor { }
public interface INotification { }
public interface IOpSerializable { }
public interface IBPMPackagedNotification { }
public interface ILanNotification { }
public interface ISensNotification { }
[Serializable]
[WebAPINotification(Type = typeof(CSensor), Group = "Sensor")]
public class SensorsStateModeNotification : SensorNotification, IBPMPackagedNotification { }
public abstract class SensorNotification : BasicLanNotification, ISensNotification { }
[Serializable]
public class BasicLanNotification : BasicNotification, ILanNotification { }
[Serializable]
public abstract class BasicNotification : INotification, ISerializable, IOpSerializable
{
long m_sentAt;
ENotificationGateway m_NotifyGateway;
[JsonIgnore]
public long SentAt
{
get
{
return m_sentAt;
}
set
{
m_sentAt = value;
}
}
/// <summary>
///
/// </summary>
[JsonIgnore]
public ENotificationGateway NotificationGateway
{
get
{
return m_NotifyGateway;
}
set
{
m_NotifyGateway = value;
}
}
#region ISerializable Members
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
// Comment the lines below not to have this serialized
info.AddValue("NotificationGateway", this.NotificationGateway);
info.AddValue("SentAt", this.SentAt);
}
#endregion
}
public enum ENotificationGateway { First, Second }
public static void Test()
{
BasicNotification msg = new BasicLanNotification
{
SentAt = 123,
NotificationGateway = ENotificationGateway.First
};
var str = JsonConvert.SerializeObject(
msg,
Newtonsoft.Json.Formatting.Indented,
new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All
});
Console.WriteLine(str);
}
}
public class NotificationPropertyResolver : DefaultContractResolver
{
public NotificationPropertyResolver()
{
IgnoreSerializableAttribute = true;
IgnoreSerializableInterface = true;
}
}
Related
I have the following base class:
public class Base
{
public string LogicalName { get; set; }
public int NumberOfChars { get; set; }
public Base()
{
}
public Base(string logicalName, int numberOfChars)
{
LogicalName = logicalName;
NumberOfChars = numberOfChars;
}
}
and the following derived classes:
public class Derived1 : Base
{
public const string EntityLogicalName = "Name1";
public const int EntityNumberOfChars = 30;
public Derived1() : base(EntityLogicalName, EntityNumberOfChars)
{
}
}
public class Derived2 : Base
{
public const string EntityLogicalName = "Name2";
public const int EntityNumberOfChars = 50;
public Derived2()
: base(EntityLogicalName, EntityNumberOfChars)
{
}
}
and I also have this function that is provided by a service:
public IEnumerable<T> GetEntities<T>(string entityName, int numberOfChars) where T : Base
{
//Some code to get the entities
}
My problem is how can I call this function generically? I want to call it with something that looks like this:
public void TestEntities<T>() where T : Base
{
var entities = GetEntities<T>(T.EntityLogicalName, T.EntityNumberOfChars);
//some other code to test the entities
}
This of course doesn't work because at this point T is not known. How can I accomplish something similar to this? EntityLogicalName and EntityNumberOfChars are characteristics that all Base derived classes have and they never change for each derived class. Can I get them from the Base class without instantiating objects or some other way that I am not seeing?
Replace constants with getter abstract properties
public abstract class Base
{
public abstract string LogicalName { get; }
public abstract int NumberOfChars { get; }
public Base()
{
}
}
public class Derived1 : Base
{
public string LogicalName { get { return "Name1"; } }
public int NumberOfChars { get { return 30; } }
public Derived1() : base()
{
}
}
Also, you will be able to put some logic into overriden getter, e.g. :
...
public string LogicalName { get { return this.EntityMap.Name; } }
...
UPDATE: The fact that you do not want to instantiate object from class but want to be able to get that string in a strongly typed manner can be handled in one more way. It is totally separate from answer above ( Since you can't override static props in c#). Consider the following code. We are adding one more class here, but LocatorInner can be a member of BaseClass. We are using this approach a lot in several existing apps.:
public class Locator
{
public static class LocatorInner<T> where T : BaseClass
{
public static string Name { get; set; }
}
public static string GetName<T>() where T : BaseClass
{
return LocatorInner<T>.Name;
}
public static void SetName<T>(string name) where T : BaseClass
{
LocatorInner<T>.Name = name;
}
}
public class BaseClass
{
}
public class DerivedClass: BaseClass
{
static DerivedClass()
{
Locator.LocatorInner<DerivedClass>.Name = "me";
}
}
public class TestClass<T> where T : BaseClass
{
public void Method()
{
var name = Locator.GetName<T>();
}
}
IMHO, I believe using constants here is a bad design decision.
You can either solve the issue using #vittore approach, but for me it sounds like you should use meta-programming with attributes if you're looking to get data from the T generic argument
For example, what about:
public class LogicalNameAttribute : Attribute
{
public LogicalNameAttribute(string name)
{
Name = name;
}
public string Name { get; private set; }
}
public class NumberOfCharsAttribute : Attribute
{
public NumberOfCharsAttribute (int number)
{
Number = number;
}
public string Number { get; private set; }
}
[LogicalName("Name1"), NumberOfChars(30)]
public class Derived1 : Base
{
public Derived1() : base()
{
}
}
Now your service method can extract attribute metadata as follows:
public void TestEntities<T>() where T : Base
{
LogicalNameAttribute logicalNameAttr = typeof(T).GetCustomAttribute<LogicalNameAttribute>();
NumberOfCharsAttribute numberOfCharsAttr = typeof(T).GetCustomAttribute<NumberOfCharsAttribute >();
Contract.Assert(logicalNameAttr != null);
Contract.Assert(numberOfCharsAttr != null);
string logicalName = logicalNameAttr.Name;
int numberOfChars = numberOfCharsAttr.Number;
// Other stuff
}
There's a performance penalty because you need to use reflection to get attributes applied to T, but you gain the flexibility of not forcing derived classes to provide this static info.
As #vittore mentioned, move the properties to base,pass the hard coded values from derived and in creation use just defautl(T)
public IEnumerable<T> GetEntities<T>(string entityName, int numberOfChars) where T : Base
{
yield return default(T); //Is its always class use new constraint and return new T();
}
I have a the following C# classes and interfaces:
class NativeTool
class NativeWidget: NativeTool
class NativeGadget: NativeTool
// above classes defined by the API I am using. Below classes and interfaces defined by me.
interface ITool
interface IWidget: ITool
interface IGadget: ITool
class MyTool: NativeTool, ITool
class MyWidget: NativeWidget, IWidget
class MyGadget: NativeGadget, IGadget
Now, I would like MyTool to keep a list of children. The children will all conform to ITool and inherit from NativeTool. The classes MyTool, MyWidget, and MyGadget all fit these criteria.
My question is, is there any way to tell MyTool that its children will always inherit from both NativeTool and ITool? I can do one or the other easily enough. But both?
You may do something like:
public class MyTool<T,U> where T: ITool where U: NativeTool
{
}
and create this like:
var tool = new MyTool<MyWidget, MyWidget>();
and also derivates, like
public class MyWidget : MyTool<....>
{
}
This appears to do it. An annoying number of wrappers, but it gets the job done, without duplicating storage.
public interface ITool { }
public interface IWidget : ITool { }
public class NativeTool { }
public class NativeWidget : NativeTool { }
public class MyTool : NativeTool, ITool, INativeTool {
public MyTool() {
this.Children = new List<INativeTool>();
}
public ITool InterfacePayload { get { return this; } }
public NativeTool NativePayload { get { return this; } }
public List<INativeTool> Children { get; set; }
public NativeTool NativeChild(int index) {
return this.Children[index].NativePayload;
}
public ITool InterfaceChild(int index) {
return this.Children[index].InterfacePayload;
}
public void AddChild(MyTool child) {
this.Children.Add(child);
}
public void AddChild(MyWidget child) {
this.Children.Add(child);
}
}
public class MyWidget : NativeWidget, IWidget, INativeTool {
public ITool InterfacePayload { get { return this; } }
public NativeTool NativePayload { get { return this; } }
}
public interface INativeTool {
// the two payloads are expected to be the same object. However, the interface cannot enforce this.
NativeTool NativePayload { get; }
ITool InterfacePayload { get; }
}
public class ToolChild<TPayload>: INativeTool where TPayload : NativeTool, ITool, INativeTool {
public TPayload Payload { get; set; }
public NativeTool NativePayload {
get {return this.Payload;}
}
public ITool InterfacePayload {
get { return this.Payload; }
}
}
I'm wondering about what's the way to go, if I need to publicate data-interfaces but want to use them internal with extended calculated properties. To make it clearer:
// The public interface
public interface IData
{
int Property { get; }
}
// The internal interface
internal interface IExtendedData : IData
{
int ExtendedProperty { get; }
}
// The assumed implementation of someone using my interface
public class Data : IData
{
public Data(int a)
{
Property = a;
}
public int Property
{
get;
private set;
}
public override string ToString()
{
return Property.ToString();
}
}
// My implementation
internal class ExtendedData : IExtendedData
{
public ExtendedData(int a)
{
Property = a;
}
public int Property
{
get;
private set;
}
public int ExtendedProperty
{
get
{
return 2 * Property;
}
}
public override string ToString()
{
return Property.ToString() + ExtendedProperty.ToString();
}
}
// publicated by me, for the person who uses my dll
public static class Calculations
{
public static int DoSomeCalculation(IData data, int parameter)
{
// This probably don't work, but maybe shows what I want to do
IExtendedData tempData = (ExtendedData)data;
return tempData.ExtendedProperty * parameter;
}
}
I'm realy frustrated, cause I feel like missing some basical programing skills.
You could solve this problem by implementing ExtendedData as a Wrapper for a class implementing IData
internal class ExtendedData : IExtendedData
{
private IData data;
public ExtendedData(IData data)
{
this.data = data;
}
public int Property
{
get { return data.Property; }
private set { data.Property = value; }
}
public int ExtendedProperty
{
get
{
return 2 * Property;
}
}
}
and use this in DoSomeCalculation like
IExtendedData tempData = new ExtendedData(data);
ExtendedData could inherit from Data:
class ExtendedData : Data
{...}
And for creation of a Data object you add a factory like so:
public class DataFactory
{
public IData CreateData()
{
return new ExtendedData();
}
}
User have to create all its Data objects by this factory. You can ensure it by making Data's constructor internal.
In your DLL you can then cast to ExtendedData.
I have a couple of standard ASP.NET web methods that I'm calling from javascript with a parameter that is of a custom class in form
[DataContract]
[KnownType(typeof(MyOtherSubclass))]
public class MyClass
{
[DataMember]
public MyOtherClass MyMember { get; set; }
}
where MyOtherClass is a class marked with Serializable but not with DataContract attribute (I don't have a control over its generation). There is a couple of subclasses of MyOtherClass, e.g. MyOtherSubclass :
[Serializable]
public class MyOtherSubClass : MyOtherClass
{
private string valueField;
public string Value
{
get { return valueField; }
set { valueField = value; }
}
}
When I use the DataContractJsonSerializer to serialize an object of MyClass directly, I get a result similar to
{ "MyMember" : { "__type" : "MyOtherSubClass:#Namespace", "valueField" : "xxx" } }
However, when I pass such a JSON into the web method request from javascript, I get an exception while deserializing. I have experimented a little bit and found that when using the following one instead
{ "MyMember" : { "___type" : "Namespace.MyOtherSubClass", "Value" : "xxx" } }
the deserialization works without any problems.
Is there any way to configure the DataContractJsonSerializer in such a way that it would produce the JSON in the second form, so that the web method arguments deserialization would work ?
ASP.NET WebMethods use JavaScriptSerializer, so try serializing with it. You might need a custom type resolver in order to include this property:
public class Parent
{
public string ParentProp { get; set; }
}
public class Child: Parent
{
public string ChildProp { get; set; }
}
public class CustomResolver : JavaScriptTypeResolver
{
public override Type ResolveType(string id)
{
return Type.GetType(id);
}
public override string ResolveTypeId(Type type)
{
return type.ToString();
}
}
class Program
{
static void Main(string[] args)
{
var o = new Child
{
ParentProp = "parent prop",
ChildProp = "child prop",
};
var serializer = new JavaScriptSerializer(new CustomResolver());
var s = serializer.Serialize(o);
Console.WriteLine(s);
}
}
I would like to only force the implementation of a C# getter on a given property from a base abstract class. Derived classes might, if they want, also provide a setter for that property for public use of the statically bound type.
Given the following abstract class:
public abstract class Base
{
public abstract int Property { get; }
}
If I want a derived class that also implements a setter, I could naively try:
public class Derived : Base
{
public override int Property
{
get { return field; }
set { field = value; } // Error : Nothing to override.
}
private int field;
}
But then I get a syntax error since I try to override the non existing setter. I tried some other way such as declaring the base setter private and such and I still stumble upon all kind of errors preventing me from doing that. There must be a way to do that as it doesn't break any base class contract.
Incidentaly, it can be done with interfaces, but I really need that default implementation.
I stumbled into that situation so often, I was wondering if there was a hidden C# syntax trick to do that, else I will just live with it and implement a manual SetProperty() method.
You can't do it directly, since you can't new and override with the same signature on the same type; there are two options - if you control the base class, add a second property:
public abstract class Base
{
public int Property { get { return PropertyImpl; } }
protected abstract int PropertyImpl {get;}
}
public class Derived : Base
{
public new int Property {get;set;}
protected override int PropertyImpl
{
get { return Property; }
}
}
Else you can introduce an extra level in the class hierarchy:
public abstract class Base
{
public abstract int Property { get; }
}
public abstract class SecondBase : Base
{
public sealed override int Property
{
get { return PropertyImpl; }
}
protected abstract int PropertyImpl { get; }
}
public class Derived : SecondBase
{
public new int Property { get; set; }
protected override int PropertyImpl
{
get { return Property; }
}
}
Would this suit your needs?
public abstract class TheBase
{
public int Value
{
get;
protected set;
}
}
public class TheDerived : TheBase
{
public new int Value
{
get { return base.Value; }
set { base.Value = value; }
}
}
The virtual was removed, but the base value is still the only storage for the value. So this should show '5'. And the compiler should fuss about b.Value = 4;
TheDerived d = new TheDerived();
d.Value = 5;
TheBase b = d;
//b.Value = 4; // uncomment for compiler error
cout << "b.Value == " << b.Value << endl;
-Jesse
What about something like:
public abstract class Base
{
public virtual int Property
{
get { return this.GetProperty(); }
set { }
}
protected abstract int GetProperty();
}
I had a similar requirement where I needed an interface to be able to share common sorting functionality between two loosely related classes. One of them had a read-only Order property and the other had a read-write Order property, but I needed a way to read the property the same way from both classes.
It turns out that this can be done by hiding the read-only value in a derived interface. Here is how I did it.
interface ISortable
{
int Order { get; }
}
interface ISortableClass2
: ISortable
{
// This hides the read-only member of ISortable but still satisfies the contract
new int Order { get; set; }
}
class SortableClass1
: ISortable
{
private readonly int order;
public SortableClass1(int order)
{
this.order = order;
}
#region ISortable Members
public int Order
{
get { return this.order; }
}
#endregion
}
class SortableClass2
: ISortableClass2
{
#region ISortableClass2 Members
public int Order { get; set; }
#endregion
}
class RunSorting
{
public static void Run()
{
// Test SortableClass1
var list1 = new List<SortableClass1>();
list1.Add(new SortableClass1(6));
list1.Add(new SortableClass1(1));
list1.Add(new SortableClass1(5));
list1.Add(new SortableClass1(2));
list1.Add(new SortableClass1(4));
list1.Add(new SortableClass1(3));
var sorted1 = SortObjects(list1);
foreach (var item in sorted1)
{
Console.WriteLine("SortableClass1 order " + item.Order);
}
// Test SortableClass2
var list2 = new List<SortableClass2>();
list2.Add(new SortableClass2() { Order = 6 });
list2.Add(new SortableClass2() { Order = 2 });
list2.Add(new SortableClass2() { Order = 5 });
list2.Add(new SortableClass2() { Order = 1 });
list2.Add(new SortableClass2() { Order = 4 });
list2.Add(new SortableClass2() { Order = 3 });
var sorted2 = SortObjects(list2);
foreach (var item in sorted2)
{
Console.WriteLine("SortableClass2 order " + item.Order);
}
}
private static IEnumerable<T> SortObjects<T>(IList<T> objectsToSort) where T : ISortable
{
if (objectsToSort.Any(x => x.Order != 0))
{
return objectsToSort.OrderBy(x => x.Order);
}
return objectsToSort;
}
}
You may do this with a constructor as following;
public abstract class Base
{
public abstract int Property { get; }
}
public class Derived : Base
{
public Derived(string Property) : base(Property)
{
}
}