I have a linq table "KUND" who is read only to me. It has some special characters in it to which i have writter a function to switch them out to the ones i want.
public static string changeSpecialCharacters(string kund)
{
StringBuilder b = new StringBuilder(kund);
b = b.Replace("Õ", "å");
b = b.Replace("┼", "Å");
b = b.Replace("õ", "ä");
b = b.Replace("─", "Ä");
b = b.Replace("÷", "ö");
b = b.Replace("Í", "Ö");
b = b.Replace("'", " ");
b = b.Replace("¦", "´");
b = b.Replace("Ï", "Ø");
return b.ToString();
}
I now have two questions:
1 Can i add this function to the GET in the autogenerated datacontext so i dont have to call it all over my code? Ive added it but it seems to be deleted whenever i change how my datacontext is (add/remove table). 2 Any suggestions how to make that function better in regards to speed perhaps?
Never edit the .designer.cs; instead, add a second file, and use partial class to add the method, for example:
namespace Your.Namespace
{
partial class YourDataContext
{
// your methods here
}
}
No; you can't add this to the get. Another alternative, though, is an extension method:
namespace Some.Utility.Namespace
{
public static class SomeUtilityClass
{
public static string ChangeSpecialCharacters(this string kund)
{ ... } // note the "this" in the above line
}
}
Now you can use:
string name = obj.Name.ChangeSpecialCharacters();
personally I would rename this to clarify the direction of the change, and have two methods - one to encode, one to decode.
Re doing this for a set of data; perhaps:
public static IEnumerable<SomeType> ChangeSpecialCharacters(
this IEnumerable<SomeType> items)
{
foreach(var item in items)
{
item.Name = item.Name.ChangeSpecialCharacters();
item.Foo = item.Foo.ChangeSpecialCharacters();
...
item.Bar = item.Bar.ChangeSpecialCharacters();
yield return item;
}
}
probably you could initialize your variable as:
private string kund;
public string Kund
{
get
{
return changeSpecialCharacters(string kund);
}
set
{
kund = value;
}
}
Related
I have a class with 10 properties and I am using reflection to assign values to these properties. My Property names are like,
private double? _col1;
public double? Col1
{
get
{
return _col1;
}
set
{
_col1 = value;
OnPropertyChanged("Col1");
}
}
private double? _col2;
public double? Col2
{
get
{
return _col2;
}
set
{
_col2 = value;
OnPropertyChanged("Col2");
}
}
And I am using them like,
MyClass md = new MyClass();
PropertyInfo[] properties = typeof(MyClass).GetProperties();
{
foreach (PropertyInfo property in properties)
{
double? d1 = from some method();
if (property.PropertyType == typeof(Double?))
{
if (property.GetValue(md) == null)
{
property.SetValue(md, d1);
}
}
}
}
Here I want to use an orderby property name of the class. How ??
PropertyInfo[] properties = typeof(MyClass).GetProperties();
You need to sort properties alphabetically based on their name.
Add the following line before the foreach() loop
Array.Sort(properties, (x,y)=> x.Name.CompareTo(y.Name)
I think this is an XY problem.
I think what you actually need could be something like this:
public class MyClass
{
public ObservableCollection<double?> Cols { get; }
public MyClass(int initialSize)
{
if(initialSize < 0)
{
throw new ArgumentOutOfRangeException(nameof(initialSize));
}
Cols = new(Enumerable.Repeat((double?)null, initialSize));
}
}
Then, ditching the reflection, you can just use a for loop on the observable collection. The observable collection is great cause it already raises events informing about changes.
MyClass md = new MyClass(2);
for (int i = 0; i < md.Cols.Count; i++)
{
double? d1 = from some method();
if (md.Cols[i] is null)
{
md.Cols[i] = d1;
}
}
Then, if someone needs to listen to changes made to Cols, they subscribe to the Cols.CollectionChanged event.
Order of properties in reflection is the same as in their declaration in program code. Property declared first is first. Property declared second is second. I have never tested myself, but in case of partial classes, when a class is split into several files, the situation might be tricky.
how we can ensure that it takes first Col1, then secondly Col2, etc ??
To ensure, You should use names of the properties. Example
if (property.Name == nameof(MyClass.Col1))
{
property.SetValue(instanceOfClassName, value);
}
Alternative for if is switch statement
switch (property.Name)
{
case nameof(MyClass.Col1):
break;
case nameof(MyClass.Col2):
break;
}
If you want to order the properties by name then simply use OrderBy LINQ query
var orderedByNameProperties = properties.OrderBy(property => property.Name);
I have the following code. Is it possible to use reflection to get rid of the first two parameters since the information can be found in the Action assign (Or Expression), which will always have the form of b.P... = a.P...?
class A { .... }; var a = new A { P1 = .... } // class A and B are totally different clas
class B { .... }; var b = new B { P1 = .... } // But they have some properties with the same names
....
AssignAndDoSth(a.P1, b.P1, () => b.P1 = a.P1);
private void AssignAndDoSth<T>(T curr, T prev, Action assign) // assign can be Expression
{
if (!EqualityComparer<T>.Default.Equals(curr, prev))
{
assign();
Do(prev);
....
}
}
The short answer would be "I strongly advise against it"; in reality, this is actually an instance method of a compiler-generated capture class; so you would need to deconstruct the IL of the target method, and evaluate that IL against the fields of the target instance. Not good. What that actually looks like is something like:
var ctx = new SomeType();
ctx.a = new A { P1 = .... };
ctx.b = new B { P1 = .... };
AssignAndDoSth(a.P1, b.P1, new Action(ctx.SomeMethod));
...
class SomeType {
public A a;
public B b;
public void SomeMethod()
{
b.P1 = a.P1;
}
}
The other approach would be to refactor to an Expression<Action> - but that doesn't change the work involved much - it just presents a more friendly API (relatively speaking).
Either way, all that inspection will have a non-trivial performance cost.
An expression tree may not contain an assignment operator, but can contain operator ==
static void AssignAndDoSomething<T>(T curr, T prev, Expression<Func<bool>> assign)
{
var logExpr = assign.Body as System.Linq.Expressions.BinaryExpression;
//output rid of the first parameter
Console.WriteLine(logExpr.Left);
//output rid of the second parameter
Console.WriteLine(logExpr.Right);
//assign first parameter
Expression.Lambda<Action>(Expression.Assign(logExpr.Left, Expression.Constant(curr))).Compile()();
//assign second parameter
Expression.Lambda<Action>(Expression.Assign(logExpr.Right, Expression.Constant(prev))).Compile()();
}
class A
{
public int P1;
}
class B
{
public int P1;
}
var a = new A();
var b = new B();
AssignAndDoSomething(a.P1, b.P1, () => b.P1 == a.P1);
I have an immutable struct and would like to keep it immutable, but also allow schematics like var p2 = p1.v = 3. I thought that the following might work, but it appears not:
public struct Number {
readonly int n;
public int N {
get{ return n; }
set{ return new Number(value); }
}
public Number(int newN) {
n = newN;
}
}
Is there any way to get var p2 = p1.v = 3 or var p2 = (p1.v = 3) to work?
No, there is no syntax like this that will work. Setters are, well, setters, not a way to get something.
First of all you want to do something that no one will be able to read. If you structure is immutable what one should expect as result of p1.v = 3? Obviously p1 should not change, no one expect setter to return value... the only reasonable behavior would be to see an exception "This object is immutable", but than lack of setter would be much better indication of the property being read only....
Possibly you trying to implement something like fluent interface which is much more common:
var newValue = oldValue.WithOneProperty(5).WithOtherProperty(3);
class Number
{
int oneProperty;
int otherProperty;
Number WithOneProperty(int v) { return new Number(v, this.otherProperty); }
Number WithOtherProperty(int v) { return new Number(this.oneProperty, v); }
}
You should only return values from getters.
I think there is a valid use for this with one-time-tokens or keys. I used some of the code here to generate this:
public class MyController : Controller
{
private static string m_oneTimeKey = "this key hasn't been initialised yet";
private string oneTimeKeyGet()
{
// Return the last key
string returnValue = MyController.m_oneTimeKey;
// Generate a new random key so the one we return can't be reused
var m_oneTimeKey = GetRandomString();
return returnValue;
}
private string oneTimeKeySet()
{
// Generate a new random key
var newValue = GetRandomString();
m_oneTimeKey = newValue;
return newValue;
}
private string GetRandomString()
{
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var random = new Random();
var returnValue = new string(
Enumerable.Repeat(chars, 8)
.Select(s => s[random.Next(s.Length)])
.ToArray());
return returnValue;
}
And then I use it with:
var myURL = "/Index?id=" + ID + "&key=" + oneTimeKeySet();
And within the ActionResult I can verify if this is the one time call with:
public ActionResult Index(Guid id, string key)
{
if (key == oneTimeKeyGet() {
....
}
}
}
I've actually gone a step further and I also have a static key that is passed between functions that is also checked for in the if in the ActionResult.
I'm working on some C# code where I have several files that use the same public variables (let's call these variables a, b, and c for now). Disclaimer: please don't berate me on the quality of the code, I didn't write it, it's simply my job to fix it. These variables are public and shared across all files, and should really be an array (a, b, and c all do the same thing, with slightly different properties). I am modifying the largest file of the bunch to take out all references to the variables and replace them with an array letters[], but other files contain disparate references to these variables. Is there any way to, in other files, define a variable or macro of some kind so that I don't have to change every reference in every file?
For example: In the biggest file "main.cs", I used to have:
public string a;
public string b;
public string c;
a = "a";
b = "b";
c = "c";
but I fixed it to have:
string[] letters;
letters[0] = "a";
//etc
Now, in file "small.cs", I have
a = "hello world";
b = "goodbye world";
Instead of having to go through every single file, is there any way that I could just have 'a' be defined as the first element of letters (letters[0]), b reference letters[1], etc? This way, the program would still run, and in the small files, C# would know that any reference to 'a' really means a references to letters[0].
Use a property:
public string A { get { return letters[0]; } }
Reference them from a property:
public string a
{
get
{
return letters[0];
}
set
{
letters[0] = value;
}
}
instead of writing
public string a;
public string b;
public string c;
a = "a";
b = "b";
c = "c";
write
private List<string> vals = new List<string>{ "a", "b", "c" };
public string a { get { return vals[0]; } set { vals[0] = value; } }
public string b { get { return vals[1]; } set { vals[1 = value; } }
public string c { get { return vals[2]; } set { vals[2] = value; } }
I would like to get property name when I'm in it via reflection. Is it possible?
I have code like this:
public CarType Car
{
get { return (Wheel) this["Wheel"];}
set { this["Wheel"] = value; }
}
And because I need more properties like this I would like to do something like this:
public CarType Car
{
get { return (Wheel) this[GetThisPropertyName()];}
set { this[GetThisPropertyName()] = value; }
}
Since properties are really just methods you can do this and clean up the get_ returned:
class Program
{
static void Main(string[] args)
{
Program p = new Program();
var x = p.Something;
Console.ReadLine();
}
public string Something
{
get
{
return MethodBase.GetCurrentMethod().Name;
}
}
}
If you profile the performance you should find MethodBase.GetCurrentMethod() is miles faster than StackFrame. In .NET 1.1 you will also have issues with StackFrame in release mode (from memory I think I found it was 3x faster).
That said I'm sure the performance issue won't cause too much of a problem- though an interesting discussion on StackFrame slowness can be found here.
I guess another option if you were concerned about performance would be to create a Visual Studio Intellisense Code Snippet that creates the property for you and also creates a string that corresponds to the property name.
Slightly confusing example you presented, unless I just don't get it.
From C# 6.0 you can use the nameof operator.
public CarType MyProperty
{
get { return (CarType)this[nameof(MyProperty)]};
set { this[nameof(MyProperty)] = value]};
}
If you have a method that handles your getter/setter anyway, you can use the C# 4.5 CallerMemberName attribute, in this case you don't even need to repeat the name.
public CarType MyProperty
{
get { return Get<CarType>(); }
set { Set(value); }
}
public T Get<T>([CallerMemberName]string name = null)
{
return (T)this[name];
}
public void Set<T>(T value, [CallerMemberName]string name = null)
{
this[name] = value;
}
I'd like to know more about the context in which you need it since it seems to me that you should already know what property you are working with in the property accessor. If you must, though, you could probably use MethodBase.GetCurrentMethod().Name and remove anything after get_/set_.
Update:
Based on your changes, I would say that you should use inheritance rather than reflection. I don't know what data is in your dictionary, but it seems to me that you really want to have different Car classes, say Sedan, Roadster, Buggy, StationWagon, not keep the type in a local variable. Then you would have implementations of methods that do the proper thing for that type of Car. Instead of finding out what kind of car you have, then doing something, you then simply call the appropriate method and the Car object does the right thing based on what type it is.
public interface ICar
{
void Drive( decimal velocity, Orientation orientation );
void Shift( int gear );
...
}
public abstract class Car : ICar
{
public virtual void Drive( decimal velocity, Orientation orientation )
{
...some default implementation...
}
public abstract void Shift( int gear );
...
}
public class AutomaticTransmission : Car
{
public override void Shift( int gear )
{
...some specific implementation...
}
}
public class ManualTransmission : Car
{
public override void Shift( int gear )
{
...some specific implementation...
}
}
Use MethodBase.GetCurrentMethod() instead!
Reflection is used to do work with types that can't be done at compile time. Getting the name of the property accessor you're in can be decided at compile time so you probably shouldn't use reflection for it.
You get use the accessor method's name from the call stack using System.Diagnostics.StackTrace though.
string GetPropertyName()
{
StackTrace callStackTrace = new StackTrace();
StackFrame propertyFrame = callStackTrace.GetFrame(1); // 1: below GetPropertyName frame
string properyAccessorName = propertyFrame.GetMethod().Name;
return properyAccessorName.Replace("get_","").Replace("set_","");
}
FWIW I implemented a system like this:
[CrmAttribute("firstname")]
public string FirstName
{
get { return GetPropValue<string>(MethodBase.GetCurrentMethod().Name); }
set { SetPropValue(MethodBase.GetCurrentMethod().Name, value); }
}
// this is in a base class, skipped that bit for clairty
public T GetPropValue<T>(string propName)
{
propName = propName.Replace("get_", "").Replace("set_", "");
string attributeName = GetCrmAttributeName(propName);
return GetAttributeValue<T>(attributeName);
}
public void SetPropValue(string propName, object value)
{
propName = propName.Replace("get_", "").Replace("set_", "");
string attributeName = GetCrmAttributeName(propName);
SetAttributeValue(attributeName, value);
}
private static Dictionary<string, string> PropToAttributeMap = new Dictionary<string, string>();
private string GetCrmAttributeName(string propertyName)
{
// keyName for our propertyName to (static) CrmAttributeName cache
string keyName = this.GetType().Name + propertyName;
// have we already done this mapping?
if (!PropToAttributeMap.ContainsKey(keyName))
{
Type t = this.GetType();
PropertyInfo info = t.GetProperty(propertyName);
if (info == null)
{
throw new Exception("Cannot find a propety called " + propertyName);
}
object[] attrs = info.GetCustomAttributes(false);
foreach (object o in attrs)
{
CrmAttributeAttribute attr = o as CrmAttributeAttribute ;
if (attr != null)
{
// found it. Save the mapping for next time.
PropToAttributeMap[keyName] = attr.AttributeName;
return attr.AttributeName;
}
}
throw new Exception("Missing MemberOf attribute for " + info.Name + "." + propertyName + ". Could not auto-access value");
}
// return the existing mapping
string result = PropToAttributeMap[keyName];
return result;
}
There's also a custom attribute class called CrmAttributeAttribute.
I'd strongly recommend against using GetStackFrame() as part of your solution, my original version of the solution was originally the much neater:
return GetPropValue<string>();
But it was 600x slower than the version above.
Solution # 1
var a = nameof(SampleMethod); //a == SampleMethod
var b = nameof(SampleVariable); //b == SampleVariable
var c = nameof(SampleProperty); //c == SampleProperty
Solution # 2
MethodBase.GetCurrentMethod().Name; // Name of method in which you call the code
MethodBase.GetCurrentMethod().Name.Replace("set_", "").Replace("get_", ""); // current Property
Solution # 3
from StackTrace:
public static class Props
{
public static string CurrPropName =>
(new StackTrace()).GetFrame(1).GetMethod().Name.Replace("set_", "").Replace("get_", "");
public static string CurrMethodName =>
(new StackTrace()).GetFrame(1).GetMethod().Name;
}
you just need to call Props.CurrPropName or Props.CurrMethodName
Solution # 4
Solution for .NET 4.5+:
public static class Props
{
public static string GetCallerName([System.Runtime.CompilerServices.CallerMemberName] String propertyName = "")
{
return propertyName;
}
}
usage: Props.GetCallerName();
Yes, it is!
string test = "test string";
Type type = test.GetType();
PropertyInfo[] propInfos = type.GetProperties();
for (int i = 0; i < propInfos.Length; i++)
{
PropertyInfo pi = (PropertyInfo)propInfos.GetValue(i);
string propName = pi.Name;
}
Try using System.Diagnostics.StackTrace to reflect on the call stack. The property should be somewhere in the call stack (probably at the top if you're calling it directly from the property's code).