I've a working WCF service and while writing a test for it, I added the following lines.
MyServiceClient client = new MyServiceClient();
Thing thing = client.GetThing();
System.WriteLine(thing.SomeProperty);
The above works just as supposed to. Then, I was trying to perform stringification and each of the following failed in a number of ways. The first fail is on these calls.
System.WriteLine(thing);
System.WriteLine("" + thing);
System.WriteLine(thing.ToString());
It only shows the name of the class, although I've added custom ToString method to Thing class. I haven't exposed the custom ToString explicitly but it's included in the classes created for me by VS automatically, so I'm assuming that it's exposed by the parent class (i.e. Object).
public class Thing
{
public String SomeProperty { ... }
public override String ToString() { ... }
//public new String ToString() { ... }
//public String ToString() { ... }
}
What am I missing here?
Then, I though that I could implement a new property, that returns the stringification instead. However, the property, although visible when I obtain the instance of Thing, is null.
public Stringification { get { return SomeProperty + "!"; } set { } }
//public ToString { get { return SomeProperty + "!"; } set { } }
Why isn't it providing me with the actual value of the property?
Related
Given the following code;
public class CustomControl {
private object _dataItem;
public object DataItem {
get { return _dataItem; }
set { _dataItem = value; }
}
public void Update(ref string t) {
t = "test";
}
}
public class Consume {
public void Example() {
CustomControl ctrl = new CustomControl();
ctrl.DataItem = anyObject.anyProperty;
string prop = anyObject.anyProperty;
ctrl.Update(ref prop);
anyObject.anyProperty = prop;
}
}
How can I change it so that the DataItem property is itself a reference, allowing you to pre-emptively set it to point to a variable thus allowing you to call Update() without any parameters.
So the Consume class would then look similar to;
public class Consume {
public void Example() {
CustomControl ctrl = new CustomControl();
ctrl.DataItem = anyObject.anyProperty;
ctrl.Update();
// anyObject.anyProperty has been updated to "test"
}
}
So the assigment of anyObject.anyProperty is then handled internally within CustomControl
You need to store the act of setting something to a string, so store an Action<string>:
public class CustomControl {
public Action<string> SetData { get; set; }
public void Update() {
// TODO nullity check
SetData("test");
}
}
Then Consume would look like:
public class Consume {
public void Example() {
CustomControl ctrl = new CustomControl();
// store {the act of setting this property of this object to a string}
ctrl.SetData = s => anyObject.anyProperty = s;
ctrl.Update();
}
}
The Update call will set anyObject.anyProperty to test. Note that you are storing specifically the act of setting this property of the particular anyObject you refer to in the assignment to SetData.
To expand on the lambda: we want to create a value of type Action<string>, that is, a thing which takes a string and returns no result. Such a thing is going to be executable code. Prior to C# 3, to create a 'value' that was executable code, we would have had to do something like:
ctrl.SetData = delegate(string s) { someObject.SomeProperty = s; };
With this syntax it's more obvious that we're creating a method - it has a { } delimited body, it has statements in it, and it's clear there is a string parameter that is used by the body.
One thing achieved by lambda expressions in C# 3 is the ability to condense this down; loosely, the whole of
// not compilable code
delegate(parameters) { body; }
can be replaced with
// not compilable code
(parameters) => body;
and in the case where there's only one parameter
// not compilable code
parameter => body;
which is what we have here: the expression assigned to ctrl.SetData is a piece of behaviour that accepts a string (s) and sets anyObject.anyProperty to that string. The real power is in the way the C# compiler can work out the types to it know we're creating an Action<string>.
At first I didn't understand what you're trying to do. What you're looking for is the Adapter or Facade pattern. That is, you have an object with a particular interface, but you need to adapt it to a different interface or provide a simpler interface.
One way to implement these patterns is to use composition and delegate the new interface to methods on the existing interface.
public interface IUpdatable<U>
{
void Update( U newValue );
}
public abstract class CustomControl<T,U> : IUpdatable<U>
where T : Control
{
private T Control { get; set; }
protected CustomControl( T control )
{
this.Control = control;
}
public abstract void Update( U newValue );
}
public class TextBoxFacade : CustomControl<TextBox,string>, IUpdatable<string>
{
public TextBoxFacade( TextBox textbox ) : base(textbox) { }
public override void Update( string newValue )
{
this.Control.Value = newValue;
}
}
I tried to search for an answer for this problem but could not find much, most probably because I do not know how to look for it properly, so here it goes. All help is very much appreciated.
With the base class that looks like
abstract public class Property
{
private String name;
public Property(String propertyName)
{
name = propertyName;
}
public String Name
{
get { return name; }
}
abstract public override String ToString();
}
And derived classes that look like
public class StringProperty : Property
{
private String value; // different properties for different types
public StringProperty(String propertyName, String value) : base(propertyName)
{
this.value = value;
}
public String Value // different signature for different properties
{
get { return value; }
}
public override String ToString()
{
return base.Name + ": " + value;
}
}
During runtime, the function receives a collection of "Property" objects. What do I need to do to be able to obtain the "Value" of each? Do I need to have a big if statement to query the type of each "Property" object? If not, is there a more elegant solution?
I tried to define an abstract "Value" property to be overridden but since the return types are different, it did not work. I also tried playing with shadowing the "Value" property, but I could not make it work. The idea of using an COM-like Variant does not sound very appropriate, either.
Thanks a lot in advance.
EDIT:
I should have added details as to what I am trying to do. The properties are displayed in a Winforms app. Different "TextBox"es represent different properties and are filtered for proper input (depending on the type). The updated values are read back and stored. The container object will be serialized into JSON and deserialized on an Android and iPhone client and eventually these values will be passed into a layer running native C++ code doing OpenGL stuff. I don't know in advance the kind of all needed properties so as the middleman, I wanted to make my code as robust as possible while being able to feed the OpenGL engine.
You can use a generic class:
public class AnyProperty<T> : Property
{
private T value;
// ... etc
I'd really recommend making the base class an Interface by now:
public interface IProperty
{
public String Name { get; }
}
public class Property<T> : IProperty
{
public Property(String name, T value)
{
Name = name;
Value = value;
}
public String Name { get; private set; }
public T Value { get; private set; }
public override String ToString()
{
return string.Format("{0}: {1}", Name, Value)
}
}
Here is sample usage:
var intProp = new Property<int> ("age", 32);
var strProp = new Property<string> ("name", "Earl");
var enumProp = new Property<ColorEnum> ("eye color", ColorEnum.Magenta);
To make the construction even simpler, you could have a factory method:
public static Property<T> MakeProperty(string name, T value)
{
return new Property<T>(name,value);
}
var intProp = MakeProperty("age", 32);
var strProp = MakeProperty("name", "Earl");
var enumProp = MakeProperty("eye color", ColorEnum.Magenta);
Not necessarily recommended, and a bit OT:
You could make it even funkier with an extension method:
public static Property<T> AsProp<T>(this T value, string name)
{
return new Property<T>(name,value);
}
var intProp = 32.AsProp("age");
var strProp = "Earl".AsProp("name");
var enumProp = ColorEnum.Magenta.AsProp("eye color");
You would have to simply use the object type. What are you trying to accomplish? The problem here isn't the structure of your classes, it's the function that receives the collection of Property objects. It's impossible to even cast something to an unknown type, since you don't know what type of variable it needs to be stored in.
So basically, your Property.Value property needs to be of type object. In your method that uses the Property objects, you need to do something with them, and what you're doing will decide how it should be structured. Are you printing values out? Have a *Value class inheriting from an abstract PropertyValue class and override ToString() to return an appropriate string represention.
I made a few changes to your sample code and got this result...
abstract public class Property
{
private readonly String _name;
public Property(String propertyName)
{
_name = propertyName;
}
public String Name
{
get { return _name; }
}
abstract public override String ToString();
}
public class StringProperty : Property
{
private readonly dynamic _value; // different properties for different types
public StringProperty(String propertyName, dynamic value)
: base(propertyName)
{
this._value = value;
}
public dynamic Value // different signature for different properties
{
get { return _value; }
}
public override String ToString()
{
return base.Name + ": " + _value;
}
}
static void Main(string[] args)
{
StringProperty sp = new StringProperty("A double", 3.444);
StringProperty sp2 = new StringProperty("My int", 4343);
StringProperty sp3 = new StringProperty("My directory", new DirectoryInfo("Some directory"));
StringProperty sp4 = new StringProperty("My null", null);
Console.WriteLine(sp);
Console.WriteLine(sp2);
Console.WriteLine(sp3);
Console.WriteLine(sp4);
}
}
Values are properly printed to the console in the expected way.
It would require a bit of a rethink, but have you considered using the dynamic type (introduced in .net4)
Doesn't really solve your problem, but sidespteps it.
Your properties can bascically just be a
Dictionary<String, dynamic>
, the gotcha is they don't get evaluated until runtime, so you get no compiler support for typing.
so given you want
int SomeValue = MyProperties[SomePropertyName] + 10;
So if
MyProperties[SomePropertyName] = 10; // all is good
if its 76.52 or Fred, the addition will throw an exception at the point it executes.
Code is much simpler and cleaner, no extra casting and the amount of scaffolding required is minimal, BUT, you'll need to unit test code that uses the dictionary extensively and religiously.
Hi is it possible to specify a method that is the default method for a C# class? I am writing a short class to output embed code for a video, here is the basic idea:
public class EmbeddedVideo
{
public string VideoPath { get; set; }
public string ImagePath { get; set; }
public string EmbedCode()
{
return "...";
}
}
Now if I were to say:
Response.Write(new EmbeddedVideo());
It would output the result of the GetType() method. How can I specify that I would like the EmbedCode() method to be the default in this context?
Override ToString(), which gets called in many scenarios where string conversion takes place:
public override string ToString()
{
return EmbedCode();
}
The "default" you're referring to is the default implementation of Object.ToString(), which simply happens to return the type name:
The default implementation returns the fully qualified name of the type of the Object.
It sounds like by "default method" you mean "method which controls how instances of the type are displayed in methods like Write." If so what you want to do is override the ToString method.
public override string ToString() {
return EmbedCode();
}
Martin Fowler's Refactoring discusses creating Null Objects to avoid lots of
if (myObject == null)
tests.
What is the right way to do this? My attempt violates the "virtual member call in constructor" rule.
Here's my attempt at it:
public class Animal
{
public virtual string Name { get; set; }
public virtual string Species { get; set; }
public virtual bool IsNull
{
get { return false; }
}
}
public sealed class NullAnimal : Animal
{
public override string Name
{
get{ return "NULL"; }
set { }
}
public override string Species
{
get { return "NULL"; }
set { }
}
public virtual bool IsNull
{
get { return true; }
}
}
Go look up the amount of pain that interesting concepts, such as DbNull, have caused and think about if this is actually a good idea.
Protip: if you are constantly checking for null references, you probably should rethink the API a bit to help preclude null objects closer to the top of the stack.
Protip II: having something throw an exception when there is an unexpected null is actually fine and dandy. Things should go boom if you have nulls where there shouldn't be null.
I tend to agree with Wyatt Barnett's answer in that you should show restraint when creating these kinds of "null" objects. That said, there are some nice reasons for doing so. On occasion.
I also tend to agree with Supertux's answer in that the whole point of a null object is to not need to check whether or not it is null, so you should lose the IsNull property. If you really feel you need the IsNull property, then read Wyatt's response again and reconsider.
And thank you CraigTP for the nice links for more info. Good stuff.
Now I will assume that in your real code you actually have a constructor that is attempting to set the values of Name or Species (whatever your real code equivalent might be called). Otherwise, why would you get the "virtual member call in constructor" warning/error? I've run into a couple of similar problems when using the newfangled MyProperty { get; set; } shortcut myself (particularly when used in structs, and don't get me started about serialization versioning). Your solution is to not use the shortcut, but instead do it the old-fashioned way.
public class Animal {
protected Animal() { }
public Animal(string name, string species) {
_Name = name;
_Species = species;
}
public virtual string Name {
get { return _Name; }
set { _Name = value; }
}
private string _Name;
public virtual string Species {
get { return _Species; }
set { _Species = value; }
}
private string _Species;
}
public sealed class NullAnimal : Animal {
public override string Name {
get { return String.Empty; }
set { }
}
public override string Species {
get { return String.Empty; }
set { }
}
}
This solves the problem of setting your virtual properties in the constructor. Instead, you are setting your private field values (something you don't have the ability to reference if you use the shortcut). For extra credit, compile both methods, and use the Reflector to look at the resulting assemblies.
The more I use the { get; set; } shortcut, the more I dislike it.
The point of the Null Object pattern is that it doesn't require a null check to prevent a crash or error.
For example if you tried to perform an operation on the Species property and it was null - it would cause an error.
So, you shouldn't need an isNull method, just return something in the getter that won't cause the app to crash/error e.g.:
public class Animal
{
public virtual string Name { get; set; }
public virtual string Species { get; set; }
}
public sealed class NullAnimal : Animal
{
public override string Name
{
get{ return string.Empty; }
set { ; }
}
public override string Species
{
get { return string.Empty; }
set { ; }
}
}
You only use this approach if it is appropriate. Your example of an Animal object might not be a good example because it doesn't present an appropriate case where you would use this approach. For example:
Animal animal = new Animal();
if (animal.tail == null)
{
//do nothing because wagging a tail that doesn't exist may crash the program
}
else
{
animal.wagTail();
}
In this example, you should build the Animal object so that if the animal doesn't have a tail, it can successfully handle the wagTail() command without crashing.
Class Animal
{
Tail tail;
void wagTail()
{
if (this.tail == null)
{
//do nothing
}
else
{
this.tail.doTheWag();
}
}
}
Now you don't need to do a null check, but can just call animal.wagTail() regardless of whether the animal has a tail or not.
I'd like to mention here some interesting detail. Look at your class. Does it has any logic in it? This is not a class in its sense, this is a data structure. What you are trying to do is apply null object pattern to something it is not applicable to. Data structures is closer to value types, than to classes. There fore null check can be right in place to solve your problem.
Null object pattern is not something you should always follow. Null object pattern is a thing you can use to avoid Liskov's substitution principle violation, to represent a class that does nothing, because null is not appropriate substitution for a class as it is a value, but not a class.
But things are different with value types and data structures. Null is value! So in this case null check is the right thing to do.
I have following data contract class for my WCF Service:
[DataContract(Name = "MyClassDTO")]
public class MyClass
{
private string name = "Default Name";
[DataMember]
public string Name
{
get { return name; }
set { name = value; }
}
}
When I use Visual Studio's Add Service Reference function to generate a WCF Service Reference the generated DataContract looks something like this:
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name = "MyClassDTO", Namespace = "xxx")]
[System.SerializableAttribute()]
public partial class MyClassDTO : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged
{
[System.Runtime.Serialization.OptionalFieldAttribute()]
private string NameField;
[System.Runtime.Serialization.DataMemberAttribute()]
public string Name
{
get
{
return this.NameField;
}
set
{
if ((object.ReferenceEquals(this.NameField, value) != true))
{
this.NameField = value;
this.RaisePropertyChanged("Name");
}
}
}
}
That means, the default value "Default Name" gets lost and following behavior occurs:
MyClassDTO mcdto = new MyClassDTO();
serviceClient.DoSomething(mcdto);
[OperationContract]
void DoSomething(MyClass mc){
mc.Name //<-- == null but I want it to be "Default Name"
}
Is there a way configure the data contract that way, that the defined default value "Default Name" doesn't get lost?
additional information:
I use a service reference without reuse of types in referenced assemblys, e.g. on the client side the class MyClassDTO is generated an is not aware of the server side class MyClass
The only possible (but ugly and therefore not really satisfying) solution I found this far is using the OnDeserializing attribute to set the default values at the start of the deserialization an use the setter of a field to determine if the communicated value should realy be set.
[DataContract(Name = "MyClassDTO")]
public class MyClass
{
private string name;
public MyClass()
{
Init();
}
[DataMember]
public string Name
{
get{ return name; }
set
{
if (!String.IsNullOrEmpty(value))
{
name = value;
}
}
}
private void Init()
{
name = "Default Name";
}
[System.Runtime.Serialization.OnDeserializing]
private void OnDeserializing(StreamingContext ctx)
{
Init();
}
}
Hmmm.. I thought that there were some things with [DefaultValue(...)] that would work, but apparently not; I'm a bit confused why you get null, though - since you haven't told it about any default I would expect "Default Name" to get into the output. If you have some default code (or a ShouldSerialize* / *Specified) then you could try:
[DataMember(EmitDefaultValue=true)]
public string Name {
get { return name; }
set { name = value; }
}
But again - I'm not entirely sure why you are seeing a null in the first place.
I've just tested this with something based on the WCF template in VS2008, and it works fine:
using (var client = new Service1Client()) {
var result = client.GetDataUsingDataContract();
Console.Write(result.Name); // "Default Name"
}
I don't believe that XML Schema allows the description of a default value of an element. This means that, as far as a client of your service is concerned, there is no default value.
Besides which, you've done nothing to tell WCF that you mean to have a default value, so even if there were a way to communicate your intent to a client, the fact is that you're not communicating your intent.
During deserialization, the 'set' logic of your property will be executed, so you could check for null there and set to whatever your desired default is at that point.