custom attribute for string property - c#

i have a question.
I would like to do something like that:
[PutStars]
public string telephone
where PutStars could be a custom attribute for example.
PutStars acts on the string, so it replace telephone value [333-123456789] and when getting value, it retrieves for example [333-12xxxx789].
Is it possible?
Thanks a lot!

Well, you can implement a helper method and call it when getting the value:
private string _tel;
public string Tel
{
set{ _tel = value; }
get {
return _tel.PutStars();
}
}
public static string PutStars(this string str)
{
return str.Replace("1", "*");
}
Alternatively when you get the string you can do:
var starred = myObj.Tel.PutStars();

The closest you'll get to that inbuilt will probably be [PasswordPropertyText], but a: that is intended to mask an entire field, and b: it depends entirely on the UI framework you are using looking for this attribute; nothing is automatic in attributes. Your best bet, frankly, is probably to add a second property that you use for UI binding:
public string Telephone {get;set;}
public string TelephoneMasked {
get { /* your code here */ }
}
and bind to TelephoneMasked.

Related

Get private string from different class

I need to get a private string from a class, and count the frequency of words in the string.
the counting is the easy part... the bit I am struggling with is getting the string from the second class.
Heres what I am trying to get
public class GetString
{
private string myText = "this is the string that i need to get"
private string text;
public GetString()
{
text = myText
}
any and all help would be very much appreciated. I am also told I cannot edit this class
You have three options in my view:
You can make myText public.
You can return myText from another public member, preferably a property.
You can access the value via reflection (see: How to get the value of private field in C#?).
It seems that your getString class (by the way - bad naming a class with lowercase letter) contains a text property. If this property is public you can use it to get the string. If it is not public, there might be a method that exposes it. Your code is not complete, so it cannot be said for certain.
If there are no public properties or methods that expose the string, then the only way to get is through reflection
This seems rather fundemental, you have nothing in your getString class returning the string. Try something like
public class getString
{
private string myText = "this is the string that i need to get"
public String getString()
{
return myText
}
getString a = new getString();
String hiddenString = a.getString();
You cannot use the constructor for this purpose. Try this:
public class Foo
{
private string myText = "this is the string that i need to get";
public Foo()
{
}
public String GetString()
{
return this.myText;
}
}
Every method should either have the void keyword or the return type, which is in your case a String.
Use Properties (property is a member that provides a flexible mechanism to read, write, or compute the value of a private field.):
public string MyText
{
get { return myText; }
private set { myText = value; }
}
To follow on from #Petrichor, you could also potentially use interfaces:
public interface IHasText
{
string GetPrivateText();
}
public class GetString : IHasText
{
private string myText = "this is the string that i need to get";
string IHasText.GetPrivateText()
{
return myText;
}
}
var val = new GetString();
var asInterface = (IHasText)val;
string text = asInterface.GetPrivateText();

c# modify getter/setter but keep the short form

I need to do a minor check in C# setter - check if property is an empty string. Right now I ended up with structure like that:
private string property;
public string Property
{
get
{
return property;
}
set
{
if (value.IsNotEmpty())
{
property = value;
}
}
}
Instead of
public string Property { get; set; }
6 lines instead of 1. Is there a way to insert the logic, but keep it condensed and elegant?
No
Auto-properties (or the "short form") can have access modifiers, but no logic. You are stuck with the code you have.
One thing you could do is to encapsulate your string in an object that allows for an implicit cast from string (and to string), and checks IsNotEmpty before assigning to a underlying value. Also not the most elegant solution, but it would probably allow you to keep the syntactic sugar.
No, there is no syntax sugar for such cases (at least up to C# 5.0 - current for 2014).
You can format them differently and use ?: instead of if if it looks nice enough to you:
public string Property
{
get { return property; }
set { property = value.IsNotEmpty() ? value: property;}
}
It's not exactly what you ask, but perhaps you can use DataAnnotations, for not allowing an empty string. Something like this, in this case a validation exception is raised if the property is null, an empty string (""), or contains only white-space characters.
[Required]
public string Property { get; set; }
As of C# 7, properties support arrow syntax, making the following possible:
private string property;
public string Property
{
get => property;
set => property = value.IsNotEmpty() ? value : property;
}
You can always make it like this.
It does compact it but offers no performance boost doing it this way.
private string property;
public string Property { get { return property; } set { if (value.IsNotEmpty()) property = value; } }

When to use get and set in C# class declaration [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Difference between Property and Field in C# .NET 3.5+
What's the difference between using
public string Username { get; set; }
and using
public string Username;
I have always been using the first one, but wanted to understand if there is any difference between the two, and scenarios when one should prefer over the other.
public string Username { get; set; }
is a Property.
while
public string Username;
is a Public variable.
For more comparison,
Reflection works differently on variables vs. properties, so if you rely on reflection, it's easier to use all properties.
You can't databind against a variable.
Changing a variable to a property is a breaking change.
Other link
Properties vs. Public Variables
One thing you can do with properties that you can't do with fields is limit visibility for either setter or getter:
public string MyProperty { get; private set; }
Something I use quite a lot.
And something (more powerful) you can't do with fields is define them inside an interface. Suppose you want an interface that requires implementing classes to have a certain property:
public interface MyInterface
{
string MyProperty { get; }
}
Note that you do not need to have a setter here. It is entirely up to implementing classes to determine how they should set MyProperty.
Here is a very small example of one way you could use a string property over simply using a string.
Say you have a private variable called:
private string _name;
Now lets say you wanted to make that string read only? In other words, you can't change the value. You could use the following:
public string Name
{
get { return _name; }
}
It can allow you to control access to that value. Alternatively, you can have it so that that variable can only be write only doing the following:
public string Name
{
set { _name = value; }
}
Now if you put it together, it will allow you to set to value or simply get the value. See the following:
public string Name
{
get { return _name; }
set { _name = value; }
}
You may be wondering what the point of that is since it looks like you can do the same thing with a regular string, well of course but this controls direct access to the _name variable from outside classes that aren't derived from said class.
Now what if you wanted to control how that value is set? What if you want to do some calculation or perhaps you wanted to add a prefix or suffix to that value? You do the following:
public string Name
{
get
{
return _name;
}
set
{
if (value.ToLower() == "bilbo")
_name = "Bilbo Baggins";
}
}
Now, if you set the Name property of the class to bilbo, the value of _name will be set to Bilbo Baggins as opposed to if you set the property to Amy, the _name variable will contain simply, amy.
You can do this to guarantee that whatever value that the property is set to is automatically upper or lowercase, or perhaps you can do some validation on the value or something of that sort.
I hope this explains the uses of properties and how they can be useful without making it too complicated.
Properties provide you with more flexibility, especially in .NET. C# shows bias toward properties, so keep that in mind. However, as a general rule, use accessors/mutators when getting or setting needs "processing" or an accompanying action. Use fields for holding values. E.g.,
public class Name
{
public string First;
public string Last;
public string Full{ get { return this.First + " " + this.Last; } }
}

How can I override get and set methods for all properties in a class?

I have got several classes looking like the one below, and I need to do some checks in the get method and custom set methods. Adding the code in each get and set method makes everything look really messed up.
Is there a way I can override the get and set methods for all properties in an entire class?
public class Test
{
private DataRow _dr;
public Test()
{
_dr = GetData();
}
public string Name
{
get { return _dr[MethodBase.GetCurrentMethod().Name.Substring(4)].ToString(); }
set
{
VerifyAccess(MethodBase.GetCurrentMethod().Name.Substring(4), this.GetType().Name);
_dr[MethodBase.GetCurrentMethod().Name.Substring(4)] = value;
}
}
public string Description
{
get { return _dr[MethodBase.GetCurrentMethod().Name.Substring(4)].ToString(); }
set
{
VerifyAccess(MethodBase.GetCurrentMethod().Name.Substring(4), this.GetType().Name);
_dr[MethodBase.GetCurrentMethod().Name.Substring(4)] = value;
}
}
public string DescriptionUrl
{
get { return _dr[MethodBase.GetCurrentMethod().Name.Substring(4)].ToString(); }
set
{
VerifyAccess(MethodBase.GetCurrentMethod().Name.Substring(4), this.GetType().Name);
_dr[MethodBase.GetCurrentMethod().Name.Substring(4)]= value;
}
}
private void VerifyAccess(string propertyname, string classname)
{
//some code to verify that the current user has access to update the property
//Throw exception
}
private DataRow GetData()
{
//Some code to pull the data from the database
}
}
I think what you need is a Proxy on your class, read about Proxy Pattern and Dynamic Proxies
Not directly, there isn't a way to do it with just a compiler. You'd have to generate your entire binary file, then post-process it with some external tool.
This post describes a somewhat similar issue; I hope it helps.
There's a variety of ways to do it.
One would be to create a proxy class (mentioned before), but that would require a lot of refactoring on your behalf.
Another way is with aspects. These do exactly what you're after (insert code based on a pre-requisite.. i.e. all get methods in a class that inherit from x). I ran into a similar problem (actually the exact same problem - checking for security on method calls), and couldn't find cheap/free aspect software that fulfilled my needs.
So, I decided to use Mono-Cecil to inject code before function calls.
If you're interested (it gets a bit messy dealing with IL codes) I can post an old copy of the source
You should extract common code to separate get/set methods, after that you'll be able to add common logic to your properties. By the way, I would do such extraction anyway to avoid copy/paste in the code.
Smth like this:
public string Name
{
get { return GetProperty(MethodBase.GetCurrentMethod()); }
set
{
SetProperty(MethodBase.GetCurrentMethod(), value);
}
}
private string GetProperty(MethodBase method)
{
return _dr[method.Name.Substring(4)].ToString();
}
private void SetProperty(MethodBase method, string value)
{
string methodName = method.Name.Substring(4);
VerifyAccess(methodName , this.GetType().Name);
_dr[methodName] = value;
}
This can be done with indirect value access, e.g. obj.PropA.Value = obj.PropB.Value + 1 -- you can even keep strong typing information. It can be implemented with either attributes or direct-instantiation.
// attribute -- bind later in central spot with annotation application
[MyCustomProp(4)] CustProp<int> Age;
// direct -- explicit binding, could also post-process dynamically
CustProp<int> Age = new CustProp<int>(4, this);
Alternatively, perhaps using a template system such as TT4 may be a viable approach.
However, don't forget "KISS" :-)
I would love for someone to give a better answer for this.
I'm looking for an answer now… best idea I have had would be to define all the properties you want to have be validated as a generic class. For example:
public class Foo {
public String Name {
get{ return _Name.value; }
set{ _Name.value = value; }
}
private Proxy<String> _Name;
static void main(String[] args) {
Foo f = new Foo();
//will go through the logic in Proxy.
f.Name = "test";
String s = f.Name;
}
}
public class Proxy<T> {
public T value {
get {
//logic here
return _this;
} set {
//logic here
_this = value;
}
}
private T _this;
}

C# Case-Insensitive String

Considering the class below
- can I do anything to implement a case-insensitive string?
public class Attibute
{
// The Name should be case-insensitive
public string Name
{
get;
set;
}
public Attibute()
{
}
}
public class ClassWithAttributes
{
private List<Attributes> _attributes;
public ClassWithAttributes(){}
public AddAttribute(Attribute attribute)
{
// Whats the best way to implement the check?
_attributes.add(attribute);
}
}
Structure of an HTML 4 Document
I have edited the class to be a bit more objective and specific
In answer to the restructured question, you could do it like this:
public class Attribute { public string Name { get; set; } }
public class AttributeCollection : KeyedCollection<string, Attribute> {
public AttributeCollection() : base(StringComparer.OrdinalIgnoreCase) { }
protected override string GetKeyForItem(Attribute item) { return item.Name; }
}
public class ClassWithAttributes {
private AttributeCollection _attributes;
public void AddAttribute(Attribute attribute) {
_attributes.Add(attribute);
//KeyedCollection will throw an exception
//if there is already an attribute with
//the same (case insensitive) name.
}
}
If you use this, you should either make Attribute.Name read-only or call ChangeKeyForItem whenever it's changed.
You can't have case-insensitive properties—you can only have case-insensitive operations, like a comparison. If someone accesses XHtmlOneDTDElementAttibute.Name, they will get back a string with whatever case it was created with.
Whenever you use .Name, you can implement that method in a way that ignores the case of the string.
It depends what you're trying to do with the strings.
If you want to compare strings regardless of case, call String.Equals with StringComparison.OrdinalIgnoreCase.
If you want to put them in a dictionary, make the dictionary's comparer StringComparer.OrdinalIgnoreCase.
Therefore, you could make a function as follows:
public class XHtmlOneDTDElementAttibute : ElementRegion {
public bool IsTag(string tag) {
return Name.Equals(tag, StringComparison.OrdinalIgnoreCase);
}
// The Name should be case-insensitive
public string Name { get; set; }
// The Value should be case-sensitive
public string Value { get; set; }
}
If you want a more specific solution, please tell me what you're doing with the Name property
Well, my take on this, after glancing at the spec, is that there's nothing you need to do to make the string properties case-insensitive. The concept doesn't really make sense, anyway: strings aren't case-sensitive or -insensitive; operations on them (like search and sort) are.
(I know the W3C's HTML recommendations say essentially that. It's badly-phrased.)
Alternatively, you might want to make the property always uppercase, like this.
public class XHtmlOneDTDElementAttibute : ElementRegion {
string name;
// The Name should be case-insensitive
public string Name {
get { return name; }
set { name = value.ToUpperInvariant(); }
}
// The Value should be case-sensitive
public string Value { get; set; }
}

Categories

Resources