Just found LinFu - looks very impressive, but I can't quite see how to do what I want to do - which is multiple inheritance by mixin (composition/delegation as I'd say in my VB5/6 days - when I had a tool to generate the tedious repetitive delegation code - it was whilst looking for a C# equivalent that I found LinFu).
FURTHER EDIT: TO clarify what I mean by composition/delegation and mixin.
public class Person : NEOtherBase, IName, IAge
{
public Person()
{
}
public Person(string name, int age)
{
Name = name;
Age = age;
}
//Name "Mixin" - you'd need this code in any object that wanted to
//use the NameObject to implement IName
private NameObject _nameObj = new NameObject();
public string Name
{
get { return _nameObj.Name; }
set { _nameObj.Name = value; }
}
//--------------------
//Age "Mixin" you'd need this code in any object that wanted to
//use the AgeObject to implement IAge
private AgeObject _ageObj = new AgeObject();
public int Age
{
get { return _ageObj.Age; }
set { _ageObj.Age = value; }
}
//------------------
}
public interface IName
{
string Name { get; set; }
}
public class NameObject : IName
{
public NameObject()
{}
public NameObject(string name)
{
_name = name;
}
private string _name;
public string Name { get { return _name; } set { _name = value; } }
}
public interface IAge
{
int Age { get; set; }
}
public class AgeObject : IAge
{
public AgeObject()
{}
public AgeObject(int age)
{
_age = age;
}
private int _age;
public int Age { get { return _age; } set { _age = value; } }
}
Imagine objects with many more properties, used in many more "subclasses" and you start to see the tedium. A code-gernation tool would actually be just fine...
So, LinFu....
The mixin example below is fine but I'd want to have an actual Person class (as above) - what's the LinFu-esque way of doing that? Or have I missed the whole point?
EDIT: I need to be able to do this with classes that are already subclassed.
DynamicObject dynamic = new DynamicObject();
IPerson person = null;
// This will return false
bool isPerson = dynamic.LooksLike<IPerson>();
// Implement IPerson
dynamic.MixWith(new HasAge(18));
dynamic.MixWith(new Nameable("Me"));
// Now that it’s implemented, this
// will be true
isPerson = dynamic.LooksLike<IPerson>();
if (isPerson)
person = dynamic.CreateDuck<IPerson>();
// This will return “Me”
string name = person.Name;
// This will return ‘18’
int age = person.Age;
Related
I have a object class like so:
public class MyObject
{
[MaxLength(128)]
public string Name {get; set;}
}
However, when I make MyObject with a string for Name of more than 128 characters, I can set it and it works. This causes issues down the line because when I go to insert this object into the database, it exceptions due to the string being to long for that column in the table.
How would I go about making sure that a string that is too long gets truncated? And how can I detect when that happens so I can log it?
In the setter you can add some validation.
public class MyObject
{
private string name;
public string Name
{
get
{
return name;
}
set
{
if (string.IsNullOrEmpty(value) || value.Length <= 128)
{
name = value;
}
else
{
//log? do something or truncate
name = value.Substring(0, 127);
}
}
}
}
Alternatively I don't like it but I tried to make it work with an Attribute and made it easier to scale with a helper class.
public class MyObject
{
private string name;
[MaxLength(128, ErrorMessage = "String is longer than {1} characters and has been truncated.")]
public string Name
{
get { return name; }
set
{
name = value.Validate(GetType().GetProperty(MethodBase.GetCurrentMethod().Name.Substring(4)).GetCustomAttributes(false));
}
}
}
public static class Tools
{
public static string Validate(this string value, object[] attributes)
{
if (attributes.FirstOrDefault(x => x is MaxLengthAttribute) is MaxLengthAttribute maxLengthAttribute)
{
if (maxLengthAttribute.IsValid(value))
{
return value;
}
else
{
//LogMethod(maxLengthAttribute.FormatErrorMessage(maxLengthAttribute.MaximumLength.ToString()));
return value.Substring(0, maxLengthAttribute.Length - 1);
}
}
return value;
}
}
I am using this Return list in WCF example but I cannot implemment the client code correctly. The example works. I want the list transfered on the client side.
My code so far:
List<Person> aPerson = new List<Person>()
Person y = new Person()'
aPerson.Add(y.id, y.name, y.adress, y.salary, y.country)
This is the server:
[DataContract]
public class Person
{
public string Id;
public string name;
public string address;
public string salary;
public string country;
public Person()
{ }
public Person(string _id, string _name, string _address, string _salary, string _country)
{
Id = _id;
name = _name;
address = _address;
salary = _salary;
country = _country;
}
[DataMember]
public string Idps
{
get { return Id; }
set { Id = value; }
}
[DataMember]
public string nameps
{
get { return name; }
set { name = value; }
}
[DataMember]
public string addressps
{
get { return address; }
set { address = value; }
}
[DataMember]
public string salaryps
{
get { return salary; }
set { salary = value; }
}
[DataMember]
public string countryps
{
get { return country; }
set { country = value; }
}
}
public List <Person> GetData(string Id)
{
//Create a List of Person objects
List<Person>employeelist =new List<Person>();
employeelist.Add(new Person("10", "name", "myAdress", "1000", "myCountry");
}
//Return the list that contains Person objects
return employeelist;
}
I don't know how to implement the client side using the code above. The server returns the list and I want to store the list local at the client.
I think you are best off walking through a full end-to-end example as found here: http://msdn.microsoft.com/en-us/library/bb386386.aspx which should help you get up to speed with WCF.
However, as a jump start... I assume that in your interface you have decorated your method GetData with the [OperationContract] attribute?
Then on the client you need to reference the WCF Service. When adding the service you should click on the Advanced button in the lower-left corner of the dialog. Change the Collection type drop-down from System.Array to
System.Collections.Generic.List.
Finally, your client should be able to call the service with some code like this:
public void SampleClientCode()
{
using (var client = new ServiceReference1.Service1Client())
{
List<Person> results = client.GetData("12345");
// Now do something with the data... Example
string firstPersonsName = results.First().nameps;
}
}
NOTE: Your property naming convention in your Person class is not very good and should be revised.
Is this a common way to store instances in a list that can be accessed by any class. Are there any better Techniques to achieving this?
class fish
{
string species = "Gold Fish";
int age = 1;
public static list<fish> Listholder = new list<fish>();
Listholder.add(this);
}
List<T> is not thread safe, so if you want to add/remove fishs from different threads you should use ConcurrentBag<T> instead.
For example:
public class Fish
{
public string Species { get; set; }
public int Age { get; set; }
private static System.Collections.Concurrent.ConcurrentBag<Fish> Aquarium = new System.Collections.Concurrent.ConcurrentBag<Fish>();
static Fish()
{
var goldFish = new Fish { Age = 1, Species = "Gold Fish" };
PutFishIntoAquarium(goldFish);
}
public static void PutFishIntoAquarium(Fish fish)
{
Aquarium.Add(fish);
}
public static void ClearAquarium()
{
Fish someFish;
while (!Aquarium.IsEmpty)
{
TryTakeFishOutOfAquarium(out someFish);
}
}
public static bool TryTakeFishOutOfAquarium(out Fish fish)
{
if (Aquarium.TryTake(out fish))
return true;
return false;
}
public static bool TryLookAtSomeFish(out Fish fish)
{
if (Aquarium.TryPeek(out fish))
return true;
return false;
}
}
I think what you're trying to get at is a way to store a globally accessible list of fish somewhere. I.e. to have a central repository of fish that all other classes get their fish from.
If this is so, there are other ways of doing this such as the Service/Repository pattern. Keep in mind that having a mutable public static field will make testing and re-usability harder.
a Class has Properties.
the class allows you to create objects.
class fish()
{
Private String _Type;
Private Int _Age;
Private String _Species;
Public Type
{
get _Type;
set _Type = Value;
}
Public Age
{
get _Age;
set _Age = Value;
}
Public Species
{
get _Species;
set _Species = Value;
}
public new(string Type, Int Age, String Species)
{
this.Type = Type;
this.Age = Age;
this.Species = Species;
}
}
//this is your new object.
Fish SunFish = New Fish("small", 9, "Sunfish");
after creating an object you can create a list of objects
I am trying to add entries in dictionary array list but i don't know which arguments to set in the People Class in the main function.
public class People : DictionaryBase
{
public void Add(Person newPerson)
{
Dictionary.Add(newPerson.Name, newPerson);
}
public void Remove(string name)
{
Dictionary.Remove(name);
}
public Person this[string name]
{
get
{
return (Person)Dictionary[name];
}
set
{
Dictionary[name] = value;
}
}
}
public class Person
{
private string name;
private int age;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public int Age
{
get
{
return age;
}
set
{
age = value;
}
}
}
using this seem to give me error
static void Main(string[] args)
{
People peop = new People();
peop.Add("Josh", new Person("Josh"));
}
Error 2 No overload for method 'Add' takes 2 arguments
This peop.Add("Josh", new Person("Josh"));
should be this
var josh = new Person() // parameterless constructor.
{
Name = "Josh" //Setter for name.
};
peop.Add(josh);//adds person to dictionary.
The class People has the method Add which only takes one argument: a Person object. The Add on the people class method will take care of adding the it to the dictionary for you and supplying both the name (string) argument and the Person argument.
Your Person class only has a parameterless constructor, which means that you need to set your Name in the setter. You can do this when you instantiate the object like above.
For your design this would solve the problem:
public class People : DictionaryBase
{
public void Add(string key, Person newPerson)
{
Dictionary.Add(key , newPerson);
}
public void Remove(string name)
{
Dictionary.Remove(name);
}
public Person this[string name]
{
get
{
return (Person)Dictionary[name];
}
set
{
Dictionary[name] = value;
}
}
}
public class Person
{
private string name;
private int age;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public int Age
{
get
{
return age;
}
set
{
age = value;
}
}
}
And in Main:
People peop = new People();
peop.Add("Josh", new Person() { Name = "Josh" });
I am new to C# and am working on classes and understanding them. My problem is I am not understanding how to create a Get to retrieve the private variable _yourname and Set to set the private variable _yourname.
namespace WindowsFormsApplication1
{
class InputClass
{
private string _yourName;
public string _banner;
public virtual void GetInfo();
public InputClass(String _banner)
{
_banner = "Enter your name";
}
}
}
Maybe I am using the wrong function to GetInfo. But I am also wondering when I have the GetInfo if in the () I should write _yourname in it.
In C# there are properties, which have the function of public getter and setter methods in other languages:
class InputClass
{
private string _yourName;
public string _banner;
public InputClass(String _banner)
{
this._banner = _banner;
}
public string YourName
{
get { return _yourName; }
set { _yourName = value; }
}
}
But you can use auto properties, if you want:
class InputClass
{
public InputClass(String _banner)
{
Banner = _banner;
}
public string YourName
{
get; set;
}
public string Banner
{
get; set;
}
}
It sounds like you are trying to provide access to the _yourName field. If so then just use a property
class InputClass {
public string YourName {
get { return _yourName; }
set { _yourName = value; }
}
...
}
Now consumers of InputClass can access it as if it were a read only field.
InputClass ic = ...;
string yourName = ic.YourName;
ic.YourName = "hello";
Note: C# provides a special syntax for simple properties like this which are just meant to be wrappers over private fields. It's named auto-implemented properties
class InputClass {
public string YourName { get; set; }
}
You can override getters and settings using the get and set keywords. For example:
class InputClass
{
private string _yourName;
private string _banner;
public YourName
{
get { return _yourName; }
set { _yourName = value; }
}
public Banner
{
get { return _banner; }
set { _banner = value; }
}
public InputClass(String banner)
{
_banner = banner;
}
}
1.) Use properties instead of members, you get a free accessor (get) and mutator (set).
public string YourName { get; set; }
public string Banner { get; set; }
2.) You can take advantage of the default constructor, and declare it on the fly.
//the old way:
InputClass myClass = new InputClass();
myClass.YourName = "Bob";
myClass.Banner = "Test Banner";
//on the fly:
InputClass myClass = new InputClass()
{
YourName = "Bob",
Banner = "Test Banner"
}