I want to make my classes have parametr ID which identificate this class.
For example I want something like this:
class Car
{
public static virtual string ID{get{return "car";}}
}
class SuperCar : Car
{
public static override string ID{get{return "superCar";}}
}
Car a = new Car();
//a.ID == car
a = new SuperCar();
//a.ID = superCar
Do you think there is any why to make something like that ? I now I can't make virutal static :/
I may be being dense, but what you've written down is exactly what you'd get if you were not using static methods. You seem to be asking "How do I make static methods act like instance methods". The answer is...use instance methods and normal polymorphism?
If this is just to get an identifier for the class, the GetType() member will suffice.
Adam Wright hits on a good point here. Statics are not polymorphic, but it looks like the behavior being sought is that of polymorphism.
The problem seems to be that since statics exist at the class level rather than the instance level, you can't utilize polymorphism because you're not dealing with an instance which may override the behavior.
Some confusion may coming from the fact that your sample code looks like it's trying to treat the property non-statically. when accessing the Car's static ID property, that property is exposed on Car...not instance a. That may seem obivous, but it's important to remember that a call to Car.ID has nothing to do with the type of instance a. So, there's no level of inference that can be drawn from the way instance a was created; i.e. just because instance a happens to be a SuperCar, there's no way to know that the next call to Car.ID should actually be interpretted as a call to SuperCar.ID.
you can simulate polymoprhic behavior of this static property, though, by encapsulating a call to the the respective static property through a virtual instance level property...
Something like this might give you what you're looking for:
class Program
{
class Car
{
// NOTE: this can't have the same name as the static method
public virtual string CarType
{
get { return ID; }
}
public static string ID { get { return "car"; } }
}
class SuperCar : Car
{
// NOTE: this can't have the same name as the static method
public override string CarType
{
get { return ID; }
}
public static string ID { get { return "super car"; } }
}
static void Main(string[] args)
{
Car a = new Car();
Console.WriteLine(a.CarType);
a = new SuperCar();
Console.WriteLine(a.CarType);
}
}
You can just use a.GetType().Name;
I'm not sure why you'd need to do this when you can simply refer to the type itself.
var car = new SuperCar();
if (car is SuperCar)
{
...
}
or if you need the actual name as text
var className = car.GetType().Name;
A better approach to what I think you are trying to do would be to use Attributes.
[MyAttribute("Car")]
public class Car
{ ... }
Now you can use reflection to find all the attributes on your class whether you have a reference to the type, or an instance of it.
You can just remove the virtual and override keywords in your code and use the new keyword, but I still agree with tvanfosson.
Thus the property is no longer inherited from the parent class it is absolutely new one.
Related
I am asking the question regarding Immutable object pattern and implementing it. I am not talking about the existing classes in .Net library like String.
I understand that immutable objects are objects which once loaded cannot be modified by any external or internal component. What if I derive the immutable class as it is not a sealed class. Then assign the object to the base class, and call a method in the base class. I have effectively changed the state of the base immutable class as its state is that of the derived class object.
public class Person
{
private readonly string name;
public Person(string myName)
{
this.name = myName;
}
public string Name
{
get { return this.name; }
}
public void DisplayName()
{
Console.WriteLine(string.Format("Person's name is {0}", this.name));
}
}
public class AnotherPerson : Person
{
private string name1;
public AnotherPerson (string myName) : base(myName)
{
this.name1 = myName;
}
}
class Program
{
static void Main(string[] args)
{
Person me = new Prasanth("MyName");
me.DisplayName();
me = new AnotherPerson("AnotherName"); ;
me.DisplayName();
Console.ReadLine();
}
}
Output :
Person's name is MyName
Person's name is AnotherName
Let's forget about the flaws of your example (the comments already said it all) and answer your question: "why are Immutable classes not Sealed in C#."
The thing is, immutability isn't a feature of the C# language. Some languages support immutability as a feature (in which case your point would be valid), but C# doesn't. In the end, you're just building an immutable class out of existing, all-purpose features. And therefore, limitations can ensue.
Also, immutability is a precaution, not a protection. The point is to prevent anybody to change the data through "normal" means. If somebody really wants to change the data, they always can, for instance through reflection (or sub-classing, as you mentioned). But if a developer does that, then there's no way he's ignoring he's mutating data that is supposed to be read-only, and we can assume he has a good reason to do so. The point of immutability is to prevent the developer from unknowingly shooting himself in the foot, not to lock him down.
You can only assign readonly string name once. I'm currently not sure if this only possible in the constructor.
You assign it in the first run "MyName" and in the second run you assing "AnotherName" to a completly different object that you created with new AnotherPerson(...)
static void Main(string[] args)
{
Person me = new Prasanth("MyName");
me.DisplayName();
// vvvvvv here you lose the reference to the old object
me = new AnotherPerson("AnotherName"); ;
me.DisplayName();
Console.ReadLine();
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I sometimes need to go online and find a tutorial for something. I am often finding that some people put code like this:
this.button1.Text = "Random Text";
Then I find code that is just like this:
button1.Text = "Random Text";
Is it better to use the this.whatever or does it not matter?
It depends. Here's an example class:
class A
{
private int count;
public A(int count)
{
this.count = count;
}
}
In this case, the "this." is mandatory because it disambiguates the reference on the left of the assignment. Without it, it is not clear to you reading the code whether "count" would refer to the parameter or the field. (It is clear to the compiler, which has rules to follow.) But in most cases, it is purely a matter of preference.
Write all your code to emphasize salient points to the reader. If you feel that it is important for the reader to clearly understand that an identifier refers to an instance member then use this. If you feel that its an unimportant and distracting implementation detail, don't. Use good judgment to make your code readable.
this is just to make it clear, in some cases we have to use this:
Differentiate between parameter and local member:
//local member
object item;
private void SomeMethod(object item){
this.item = item;//must use this
}
Pass the current class instance into another method:
public class SomeClass {
private void SomeMethod(SomeClass obj){
//....
}
private void AnotherMethod(){
SomeMethod(this);//pass the current instance into SomeMethod
//.....
}
}
Use in extension methods:
public static class SomeClassExtension {
public static void SomeClassMethod(this SomeClass obj){
//use obj as a reference to the object calling this method...
}
}
Call a constructor from another constructor (with different signature):
public Form1(string s) : this() {//Call the Form1() before executing other code in Form1(string s)
//......
}
Use for declaring indexers:
public class SomeClass {
//declare an index returning a string
public string this[int index] {
get {return ...}
set { ... }
}
}
Use auto-properties in struct:
public struct SomeStruct {
public object AutoProp1 {get;set;}
public object AutoProp2 {get;set;}
public SomeStruct() : this() //must use this
{
AutoProp1 = someObject;
AutoProp2 = someObject;
}
}
Cast the current instance to the based classes/types:
public class ClassB : ClassC {
//...
}
public class ClassA : ClassB {
public ClassA(){
((ClassC)this).MemberOfClassC ... ;//There might be some member in ClassC
//which is overridden in ClassA or ClassB, casting to ClassC can help we invoke the original member instead of the overridden one.
}
}
There might be some other uses of this, however I'll update later if I think out.
It does not matter, it is a matter of style. I tend to omit this, since it is just extra code to mentally parse.
The only case it matters is when there is a naming conflict between local and instance variables, in which case this can be used to disambiguate between a field and a local variable.
Here is an example of the type of situation where it does matter:
public class Foo
{
private string x;
public Foo(string x)
{
// x = x; Assigns local parameter x to x, not what we want
this.x = x; // Assigns instance variable x to local parameter x: this disambiguates between the two.
}
}
an example of using this can be to access class variable when you already have a similar variable in the scope. Otherwise it is mostly of choice.
Example
public class Test
{
public string firstName { get; set; }
public void temp(string firstName)
{
firstName = this.firstName;
}
}
In regards to fields the only case where this is explicitly needed is when there is a naming conflict:
public class Foo
{
private string bar;
public Foo(string bar)
{
this.bar = bar;
}
}
So some will prepend an underscore:
public class Foo
{
private string _bar;
public Foo(string bar)
{
_bar = bar;
}
}
Usually it will not matter. This reason why you might use this. is to explicit say that you want to reference a property/field that belong to the current class.
Again, there are not many occasions when you are likely to need this, but for example you might have a local variable with the same name as a class level property/field. Then you could use this..
For example:
class MyClass
{
string s = "1";
void MyFunction(string s)
{
//s = local value as passed in to function
//this.s = "1"
}
}
It doesn't usually matter. The this keyword "refers to the current instance of the class and is also used as a modifier of the first parameter of an extension method."
Check out this article.
http://msdn.microsoft.com/en-us/library/dk1507sz.aspx
generally it doesn't matter, but if you pass in a variable called, say button1, to a class method that already has a member called button1, then you'll need to disambiguate which one you really meant.
This is probably why people now use this. to explicitly say which variable you meant, if you use this practice all the time, you'll not get it wrong in the few cases where its important.
Of course, you could ensure that all member variables are uniquely named, say with a prefix like m_, but that's fallen out of fashion nowadays, people prefer to write out this.
It really depends on the situation.
http://msdn.microsoft.com/en-us/library/dk1507sz(v=vs.80).aspx
To qualify members hidden by similar names
To pass an object as a parameter to other methods
To declare indexers
As others have already pointed out, it is useful in distinguishing field/property with method variables, One other place where this is required is to invoke Extension methods on current instance. For example this.ExtensionMethod(); would work, but not just ExtensionMethod();
Other than that, its a matter of personal choice, some call it redundant and some like to use it. It totally depends on you and your team.
Personally I like to use this with class members, specially for Forms method if working on code-behind of winform, like this.Close();
For more discussion when to use this see: When do you use the "this" keyword?
This may just be me showing my lack of knowledge / bad programming practice, but i'm curious to know if:
a) This already exists
b) If it doesn't exist, if it's bad programming practice to do so
But here's my question:
Suppose I have a class, let's call it "Computer" and it holds data of all the computers in a company. Now, it just so happens that this company has thousands of Dell computers and thousands of HPs and nothing else. (Again please stick with me here, this is just an example to illustrate my point)
Now, I could define my class as follows:
Public Class Computer
Dim Type as string
Dim SerialNumber as string
Dim User as String
...
End Class
Now, in my code I create two lists:
Dim DellComps as new list(of computer)
Dim HPComps as new list(of computer)
Obviously, for the DellComps, all them will have .Type = "Dell" and for the HPComps, all will have .Type = "HP"
Now, I know I could set this variable in the constructor very easily, but I'm wondering if there is a smarter way to declare the variable inside the class - Similar to the VB Shared / C# Static statement where all the instances of the class share the same variable.
My thoughts are:
Inherit the class and create a shared variable in the child class
Just leave it as is and declare the Type var in the constructor
Maybe this is something that could be done via interfaces somehow
MOST PROBABLE - something i just don't know about
Thanks and I hope what I'm asking makes sense!!!
The closest thing you'd have is done with the abstract keyword. You would have an abstract class Computer, that would then be overridden by the concrete subclasses DellComputer and HpComputer. A crude (C#) example would be:
public abstract class Computer
{
public string Type { get; protected set; }
}
public class DellComputer : Computer
{
public DellComputer()
{
this.Type = "Dell"
}
}
You generally don't want to share a single variable among a ton of instances because that breaks encapsulation, and more realistically can become a big problem when attempting to unit test code. So the pure form of what you're talking about isn't a terribly good idea, but the realistic use case is pretty common, and definitely supported.
EDIT: As part of the comments below, here's a different approach that uses the very closely related virtual keyword!
public abstract class Computer
{
public virtual string Type { get; }
}
public class DellComputer : Computer
{
public override string Type
{
get {
return "Dell";
}
}
}
If you are always setting a flag in the constructor indicating the type of computer (which is NOT a typical business object scenario, where the type can be edited), chances are that you can really solve your problem using subclasses.
Subclass Computer to create DellComputer and HpComputer classes.
When creating lists of each type of computer, one approach is to have a master list of all computers and use Linq's Enumerable.OfType(TResult) to select instances that match the type you are interested in.
If indeed you want the type of class to be editable after the class is created, instead provide a property to modify the type of computer. You may for convenience provide a constructor overload that also sets the property (though I would shy away from that personally). If you do, have that constructor overload use the property to set the type.
UPDATE
Example of what the factory pattern might look like.
public abstract class Computer
{
public virtual string Type { get; }
}
public class DellComputer : Computer
{
public override string Type
{
get { return "Dell"; }
}
}
public class HpComputer : Computer
{
public override string Type
{
get { return "HP"; }
}
}
// Here I'm using an enum to indicate the type desired. You might use a string
// or anything else that makes sense in your problem domain.
public enum ComputerType
{
Dell = 1,
Hp = 2
}
public class ComputerFactory
{
public Computer Create(ComputerType type)
{
switch (type)
{
case ComputerType.Dell:
return new DellComputer();
case ComputerType.Hp:
return new HpComputer();
default:
throw new InvalidArgumentException();
}
}
}
// Usage would be something like:
List<Computer> computers = new List<Computer>();
computers.Add(ComputerFactory.Create(ComputerTypes.Dell);
computers.Add(ComputerFactory.Create(ComputerTypes.Dell);
computers.Add(ComputerFactory.Create(ComputerTypes.Hp);
You could create a class that has a collection and other data
In this case PC would not have a type.
public class Computers
{
private List<Computer> pcs= new List<computer>();
public List<Computer> PCs get { return { pcs; } };
public String Brand { get; private set; }
public Computers(string brand) {Brand = brand;}
}
Regarding a static variable. You don't want all members of the class share Brand.
With the said just repeat the data in the constructor.
If a Dell has the same Properties as an HP then I would use the same class.
If you stated buying a new brand do you really want to create a new class or subclass?
If you want a structured list of brands then I would use and Enum rather than a separate class for each brand.
.Net 3.5 sp1 available type question ...
Is it possible to "get a handle" or reference to the actual instance of an assembly that called a method? I can get the executing and calling assembly via reflection, but what I'm after is not so much the assembly, but the INSTANCE of that assembly that called method.
Simple example (maybe):
interface IBob
{
int Id { get; }
void Foo();
}
public class Bob : IBob
{
private int _id = 123;
public int Id
{
get { return _id; }
}
public void Foo()
{
new OtherAssemblyClass().Bar();
}
}
public class OtherAssemblyClass
{
public void Bar()
{
//
// what I want to do here is get a reference
// to the calling INSTANCE of IBob and determine
// Bob's Id ... so something like:
//
// int Id = (System.XXX.GetCallingAssemblyInstance() as IBob).Id;
//
//
}
}
The real situation is a bit more complex than this, and precludes the obvious passing of IBob instance as a parameter in OtherAssemblyClass.Bar(), although that may be end result.
Entirely possible I'm just being stupid too, and not seeing obvious. 2 x 4 corrections to skull also welcome.
Unfortunately you can't get the instance unless it's passed in. You can find out what's calling your method by using the StackTrace.
PostSharp is the only way I would know of to make that work. Take a look at the InstanceBoundLaosEventArgs class. Warning: this is a pretty big deal, and a serious addition to the weight and complexity of your architecture, especially at build time.
I can get you halfway there if you are willing to use extension methods. Here's an example:
public static void Bar(this IBob CallingIBob)
{
int Id = CallingIBob.Id;
}
...and calling Bar():
public class Bob : IBob
{
#region IBob Members
public void Foo()
{
this.Bar();
}
public int Id
{
get { throw new NotImplementedException(); }
}
#endregion
}
Yes, it's not the exact case you were looking for, but functionally similar. Bar can be called from any bob and it will have a reference to the calling bob without explicitly passing in the instance.
I understand that you may want to call Bar in another assembly of your choice. Maybe Bar is defined in a base class and you are calling specific implementations of it in subclasses. That's ok, use the extension method to take in information about the specific Bar you are trying to access and route accordingly.
Please update your post with a more concrete problem definition if you would like a more specific solution.
All I need is a way to make a property of one class only 'settable' from one other class (a sort of manager class).
Is this even possible in c#?
My colleague 'reliably' informs me that I have a design flaw, but I feel I should at least ask the community before I concede defeat!
No, it's not really possible to do this in any clean way in C#. You probably have a design flaw ;-)
You can use the internal modifier, which lets all types in the same assembly access the data (or nominated assemblies if using [InternalsVisibleTo] - but no: there is no friend equivalent in C#.
For example:
public string Foo {get; internal set;}
You have a design flaw. Also, don't be paranoid about data hiding. Here's 3.5's way to do it:
class Program
{
static void Main(string[] args)
{
Managed m = new Managed();
Console.WriteLine(m.PrivateSetter);
m.Mgr.SetProperty("lol");
Console.WriteLine(m.PrivateSetter);
Console.Read();
}
}
public class Managed
{
private Manager _mgr;
public Manager Mgr
{
get { return _mgr ?? (_mgr = new Manager(s => PrivateSetter = s)); }
}
public string PrivateSetter { get; private set; }
public Managed()
{
PrivateSetter = "Unset";
}
}
public class Manager
{
private Action<string> _setPrivateProperty;
public Manager(Action<string> setter)
{
_setPrivateProperty = setter;
}
public void SetProperty(string value)
{
_setPrivateProperty(value);
}
}
Here's how we'd do it in pre-lambda days:
public class Managed
{
private Manager _mgr;
public Manager Mgr
{
get { return _mgr ?? (_mgr = new Manager(this)); }
}
public string PrivateSetter { get; private set; }
public Managed()
{
PrivateSetter = "Unset";
}
public class Manager
{
public void SetProperty(string value)
{
m.PrivateSetter = value;
}
private Managed m;
public Manager(Managed man)
{
m = man;
}
}
}
The best way to do it would be:
/// <summary>
/// Gets or sets foo
/// <b>Setter should only be invoked by SomeClass</b>
/// </summary>
public Object Foo
{
get { return foo; }
set { foo = value; }
}
When you have some complex access or inheritance restriction, and enforcing it demands too much complexity in the code, sometimes the best way to do it is just properly commenting it.
Note however that you cannot rely on this if this restriction has some security implications, as you are depending on the goodwill of the developer that will use this code.
You cannot do that on that way, but you can access a property's setter method from a derived class, so you can use inheritance for the purpose. All you have to do is to place protected access modifier. If you try to do so, your colleague is right :). You can try doing it like this:
public string Name
{
get{ return _name; }
protected set { _name = value; }
}
keep in mind that the set method of the property is only accessible from the derived class.
Or you could have these two classes in an assembly alone and have the setter as internal. I would vote up for the design flaw though, unless the previous answer by milot (inheriting and protected) makes sense.
You could do:
public void setMyProperty(int value, Object caller)
{
if(caller is MyManagerClass)
{
MyProperty = value;
}
}
This would mean that you could use a 'this' pointer from the calling class. I would question the logic of what you're attempting to achieve, but without knowing the scenario I can't advise any futher. What I will say is this: if it is possible to refactor your code to make it clearer, then it is often worthwhile doing so.
But this is pretty messy and certinly NOT fool-proof ... you have been warned!
Alternativly...
You could pass a delegate from the Class with the Property (Class A) to the Manager Class (Class B). The delegate can refer to a private function within A to allow B to call that delegate as any normal function. This precludes that A knows about B and potentially that A is created before B. Again... messy and not fool-proof!
You can achieve to this by making a Public property in your "settable class" that will inherit from the real class that will have a protected property... this way only the inherit class can SET and not class that doesn't inherit. But the drawback is that you will require to have an inherit class...
Reflection, though I would agree that having to do this just to get around an access modifier is probably an indication of a bad design.
public class Widget
{
private int count;
public int Count
{
get { return this.count; }
private set { this.count = value; }
}
}
public static class WidgetManager
{
public static void CatastrophicErrorResetWidgetCount( Widget widget )
{
Type type = widget.GetType();
PropertyInfo info = type.GetProperty("Count",BindingFlags.Instance|BindingFlags.NonPublic);
info.SetValue(widget,0,null);
}
}
The reason this is a design flaw is because it seems muddled between the scope of the two objects.
The properties of a class should be accessible in the context of that class, at least internally.
It sounds like the settable property on your item class is really a property of the manager class.
You could do something similar to what you want by closely coupling the two classes:
public class MyItem {
internal MyItemManager manager { get;set; }
public string Property1 {
get { return manager.GetPropertyForItem( this ); }
}
}
Unfortunately this isn't great design either.
What your looking for is what C++ calls a Friend class but neither c# or vb has this functionality. There is a lot of debate as to the merit of such functionality since it almost encourages very strong coupling between classes. The only way you could implement this in c# would be with reflection.
If your goal is to have a class Foo let some property (e.g. Bar, of type Biz) to be changed by some other object, without exposing it publicly, a simple way to do that is to have an instance of Foo which is supposed to be changeable by some other object to pass that other object an Action<Biz> which points to a private method that changes Bar to the passed-in value. The other object may use that delegate to change the Bar value of the object that supplied it.
If one wishes to have give all instances of some type Woozle the ability to set the Bar value of any instance of Foo, rather than exposing such abilities on a per-instance basis, one may require that Woozle have a public static method Woozle.InstallFooBarSetter which takes a parameter of type Action<Foo, Biz> and one of type Object. Foo should then have a static method WoozleRequestBarSetter which takes an Object, and passes it to Woozle.InstallFooBarSetter along with an Action<Foo,Biz>. The class initializer for Woozle should generate a new Object, and pass it to Foo.RequestBarSetter; that will pass the object to Woozle.InstallFooBarSetter along with a delegate. Woozle can then confirm that the passed-in object is the one that it generated, and--if so--install the appropriate delegate. Doing things this way will ensure that nobody but Woozle can get the delegate (since the delegate is only passed to Woozle.InstallFooBarSetter), and Woozle can be sure its delegate comes from Foo (since nobody else would have access to the object that Woozle created, and Woozle.InstallFooBarSetter won't do anything without it).
if it is a design flaw depends on what you want to do. You could use the StackTrace class from System.Diagnostics to get the Type of the class setting your property and then compare to the type you want to allow setting yor property..but maybe there are better ways for performing something like this (e.g. boxing)