Suppose there is such a record
public record ExampleRecord(int a, int b);
and a method
public int ExampleMethod((int a, int b) t)
{
return t.a + t.b;
}
Is it possible to do something like this to work with record as tuple parameter?
var t = new ExampleRecord(a: 1, b: 2);
ExampleMethod(t);
You can add an implicit conversion to your record type:
public record ExampleRecord(int a, int b)
{
public static implicit operator ValueTuple<int, int> (ExampleRecord record)
{
return (record.a, record.b);
}
}
Use like this:
var t = new ExampleRecord(a: 1, b: 2);
ExampleMethod(t);
You can make extension methods. For example:
public static class ExampleRecordExtensions
{
public static (int, int) ToTuple(this ExampleRecord record)
{
return (record.a, record.b);
}
}
Use like this:
var t = new ExampleRecord(a: 1, b: 2);
ExampleMethod(t.ToTuple());
Alternatively you can use deconstruction. Use like this:
var t = new ExampleRecord(a: 1, b: 2);
ExampleMethod((_, _) = t);
I remind you that record types are classes. These tuples are value types (ValueTuple). Which also means that the tuple you create form the record type will always be a copy of the data.
Related
Here is enum;
public enum myEnum{
A= 1,
B= 2,
C= 3,
D= 4,
}
I need a List contains all except D,
this way its works;
List<Enum>{myEnum.A, myEnum.B, myEnum.C}
but of course its extremely ugly. How can directly convert and filter D of this enum
Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().Where(x => x != MyEnum.D).ToList();
You can convert an enum to a list like this:
var enumList = Enum.GetValues(typeof(myEnum)).Cast<myEnum>().ToList();
And to remove myEnum.D, simply call the Remove method:
var enumList = Enum.GetValues(typeof(myEnum)).Cast<myEnum>().ToList().Remove(myEnum.D);
As mentioned in the comments, you could also add only the Enums values, which are not myEnum.D:
var enumList = Enum.GetValues(typeof(myEnum)).Cast<myEnum>().ToList().Where(val => val != myEnum.D);
You can get all the values of an enum by calling Enum.GetValues(type) (https://learn.microsoft.com/en-us/dotnet/api/system.enum.getvalues?view=netframework-4.8)
After getting all the values you can exclude certain values you don't want:
public class Program
{
public static void Main()
{
var allValues = Enum.GetValues(typeof (MyEnum))
.Cast<MyEnum>()
.Except(new[]{MyEnum.D})
.ToArray();
foreach (var val in allValues)
{
Console.WriteLine(val);
}
}
}
public enum MyEnum
{
A,
B,
C,
D
}
This will output:
A
B
C
https://dotnetfiddle.net/hdZmAK
I'm using .NET 4.6 and I experienced serious strangeness. I'm trying to get an IEnumerable of all values from a sorted set that are NOT the case-insensitive equivalent of the passed in IEnumerable. From what I understand, that is the job of Except.
I have a class, CaseInsensitiveComparer which is implemented like so:
public class CaseInsensitiveComparer : IComparer<string>, IEqualityComparer<string>
{
public static CaseInsensitiveComparer Instance { get; private set; }
static CaseInsensitiveComparer()
{
Instance = new CaseInsensitiveComparer();
}
public int Compare(string a, string b)
{
var ret = string.Compare(a, b, true);
return ret;
}
public bool Equals(string a, string b)
{
return Compare(a, b) == 0;
}
public int GetHashCode(string a)
{
return a.GetHashCode();
}
}
I use it like this:
public void DotNetWeirdness()
{
var a = new SortedSet<string>();
a.Add("A");
var b = a.Except(new string[] { "a" }, CaseInsensitiveComparer.Instance);
}
The value of b is an IEnumerable containing A. Since I'm asking for all values in SortedSet except for a/A, shouldn't I have an empty set as the result? I'm quite confused by this.
Thanks!
The issue is that you're not overriding GetHashCode. "A".GetHashCode() returns a different value from "a".GetHashCode().
A quick way to fix this is to change the GetHashCode function to this:
public int GetHashCode(string a)
{
return a.ToLower().GetHashCode();
}
Also, do you know about StringComparer? You can change your code to this:
var b = a.Except(new string[] { "a" }, StringComparer.InvariantCultureIgnoreCase);
And not have to worry about implementing your own comparer
Am a beginner in C# language
I have a class like
public class Plan
{
int a;
int b;
int c;
}
Can in any way I get the nth property of the class.
for eg: planObject.propertyIndex
This would be of great help for my project, as I am getting index number denoting the property whose value is to be changed. What I am doing right now is using if...else .
if(index ==1)
{
planObject.a = 100;
}
else if(index ==2)
{
planObject.b = 100;
}
Is there any other solution for this by using reflection?
You could use reflection, however, i would strongly advise against. Instead use a collection like List<int> or int[]. In this case, since you want to get the nth int value, you could also use a Dictionary<int, int>:
public class Plan
{
Dictionary<int, int> Values;
public Plan()
{
Values = new Dictionary<int, int>();
Values.Add(1, 100);
Values.Add(2, 200);
Values.Add(3, 300);
}
// ...
}
Now you can access the value by the number:
int value = Values[1]; // 100
Here's a list version:
public class Plan
{
List<int> Values = new List<int>();
public Plan()
{
Values.Add(100);
Values.Add(200);
Values.Add(300);
}
// ...
}
You access it via (zero based) index:
int value = Values[0]; // 100
A word of WARNING, this is in no way for beginners at all. And it might just make the code more complex. This answer takes for granted that you have a working knowledge of extension methods and reflection.
public static class PlanExtension
{
PropertyInfo _info = typeof(Plan).GetProperties();
public static void SetValue(this Plan plan, int index, int value)
{
var prop = _info[index - 1]; // So 1 maps to 0.. or 1 in this case
prop.SetValue(plan, value, null);
}
public static int GetValue(this Plan plan, int index)
{
var prop = _info[index - 1]; // Mapping magic
return (int) prop.GetValue(plan, null);
}
}
Called like this:
var p = new Plan();
p.SetValue(1, 139); // "a"
var b = p.GetValue(2); // "b"
It would help if you had a definable order to the properties, like name or something. Also, error handling is a must when it comes to reflection.
There's no "property by index" feature, but one approach that would make consumption easier would be to build an indexer on the class and encapsulate the switch statement there. Maybe something like this:
public class Plan
{
public int this[int index]
{
get
{
switch (index)
{
case 1:
return this.a;
...
}
}
set
{
switch (index)
{
case 1:
this.a = value;
...
}
}
}
}
So, now using it looks like this:
planObject[i] = 100;
Now, in your case it looks like you have an additional need because you have a key (the index) and a value (e.g. 100), so you need to store your keys and values in a Dictionary. So, in your class that uses Plan create a private field:
private Dictionary<int, int> _values = new Dictionary<int, int>
{
{ 1, 100 },
{ 2, 200 },
...
}
To use the dictionary you'd do something like this:
planObject[i] = _values[i];
UPDATE: if you can't change the class Plan then you'll need to do something like this. First you need a map from index to property name:
private Dictionary<int, string> _properties = new Dictionary<int, string>
{
{ 1, "a" },
{ 2, "b" },
...
}
and next you'll need to set that property:
var t = planObject.GetType();
var p = t.GetProperty(_properties[i]);
if (p != null)
{
p.SetValue(planObject, 100);
}
If you must use the object, instead of suggested Collections.
Plan b = new Plan();
Type t = new Type(b.GetType());
var properties = t.GetProperties();
for(int index = 0; index < properties.Length; index++)
{
properties[index].SetValue(b, 100);
}
Instead of using loop, you can pass your own index in properties array.
I hope it helps.
Here is what you want
public class Foo
{
public int A {get;set;}
public string B {get;set;}
public object GetPropertyValueAt(int index)
{
var prop = this.GetType().GetProperties()[index];
return prop.GetValue(this, null);
}
}
Usage
Foo foo = new Foo() {A = 1, B = "abc"};
int valueA = (int)foo.GetPropertyValueAt(0);
string valueB = (string)foo.GetPropertyValueAt(1);
int valueUnknown = (int)foo.GetPropertyValueAt(2); //<--- this line will give you an exception.
I have an Item and a subclass AdvancedItem (all made of value-types if that matters):
public Item
{
public string A;
public bool B;
public char C;
...// 20 fields
}
public AdvancedItem : Item
{
public string Z;
}
It's easy to simply create an Item or an AdvancedItem independently:
var item = new Item { A = "aa", B = true, C = 'c', ... };
var aItem = new AdvancedItem { A = "aa", B = true, C = 'c', ..., Z = "zz" };
Now, I just want to turn an Item into an AdvancedItem by providing it the string Z separately. In order to achieve that I was thinking of using a constructor.
Attempt A:
// annoying, we are not using the inheritance of AdvancedItem:Item
// so we will need to edit this whenever we change the class Item
public AdvancedItem(Item item, string z)
{
A = item.A;
B = item.B;
...;//many lines
Z = z;
}
Attempt B:
// to use inheritance it seems I need another constructor to duplicate itself
public Item(Item item)
{
A = item.A;
B = item.B;
...;//many lines
}
public AdvancedItem(Item item, string z) : base(Item)
{
Z = z;
}
Is there any way to improve this second attempt to avoid writing many lines of X = item.X? Maybe a solution to auto-clone or auto-duplicate a class with itself where public Item(Item item) would be wrote in one line?
Consider using AutoMapper to copy properties between objects.
This would allow the following:
Item a = new Item { A = 3, B = 'a', .... };
AdvancedItem advanced= Mapper.Map<AdvancedItem>(a);
string z = "Hello World";
advanced.Z = z;
Update
If you do not want to use AutoMapper you can use Reflection or better, Expressions. However this will make your code a bit more complex
Consider these two types:
class Item
{
public int A, B, C;
public string D, E, F;
private int privateInt;
public Item(int valueOfPrivateField)
{
privateInt = valueOfPrivateField;
}
}
class AdvancedItem : Item
{
public string G;
public AdvancedItem(int valueOfPrivateField) : base(valueOfPrivateField)
{
}
}
We can define a method that creates a field-wise copy expression. Since you mention that all your fields are value types we can just copy each field one by one to the other object:
private static void MapFields<T>(T target, T source)
{
Type type = typeof (T);
if (!Mappers.ContainsKey(type))
{
//build expression to copy fields from source to target;
var targetParam = Expression.Parameter(typeof(object));
var targetCasted = Expression.TypeAs(targetParam, typeof(T));
var sourceParam = Expression.Parameter(typeof(object));
var sourceCasted = Expression.TypeAs(sourceParam, typeof(T));
var setters = new List<Expression>();
//get all non-readonly fields
foreach (var fieldInfo in typeof(T).GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public).Where(f => !f.IsInitOnly))
{
Expression targetField = Expression.Field(targetCasted, fieldInfo);
Expression sourceField = Expression.Field(sourceCasted, fieldInfo);
setters.Add(Expression.Assign(targetField, sourceField));
}
Expression block = Expression.Block(setters);
var mapperFunction = Expression.Lambda<Action<object, object>>(block, targetParam,
sourceParam).Compile();
Mappers[type] = mapperFunction;
}
Mappers[type](target, source);
}
private static readonly Dictionary<Type, Action<object, object>> Mappers =
new Dictionary<Type, Action<object, object>>();
This caches functions that map all fields from the source to the target object, and should have close to the same performance as manually writing this.A = A, this.B = B etc.
Calling the method:
static void Main(string[] args)
{
var item = new Item(56) {A = 5, B = 6};
var advanced = new AdvancedItem(0);
MapFields(advanced, item);
int a = advanced.A; //5
int b = advanced.B; //6;
//note that advanced.privateInt == 56!
}
Please note that this code is more complex and less reliable than AutoMapper and is not recommended or ready for production systems.
One object-oriented way to implement this kind of thing for class hierarchies is to introduce a protected copy constructor in the base class (although it still requires you to write all the assignments):
public class Item
{
protected Item(Item other)
{
this.A = other.A;
this.B = other.B;
this.C = other.C;
}
public string A;
public bool B;
public char C;
// 20 fields
}
Then you would call that from the derived class like so:
public class AdvancedItem : Item
{
public AdvancedItem(Item item, string z): base(item)
{
Z = z;
}
public string Z;
}
Note that this approach does NOT prevent you from having to write all the assignment lines, but you only need to write them once, and it does mean that you now have a protected copy constructor available, which can be very useful. Also, the assignments are now all in the base class where they belong.
This approach is extendable to further derived classes. You can introduce a protected copy constructor to AdvancedItem written in terms of the public constructor (to avoid duplicated code).
For example:
public class AdvancedItem : Item
{
protected AdvancedItem(AdvancedItem other): this(other, other.Z)
{
}
public AdvancedItem(Item item, string z): base(item)
{
Z = z;
}
public string Z;
}
public class EvenMoreAdvancedItem: AdvancedItem
{
public EvenMoreAdvancedItem(AdvancedItem advancedItem, double q): base(advancedItem)
{
Q = q;
}
public double Q;
}
I would do something like this. Use a static factory method with a private constructor, and have a copy constructor defined in the base class.
AdvancedItem
{
Public Static AdvancedItem FromItem(Item i, string z)
{
AdvancedItem item = new AdvancedItem(i);
item.Z = z;
return item;
}
private AdvancedItem(Item i) : Base(i) {}
}
Then usage is AdvancedItem i = AdvancedItem.FromItem(item, extraThing);
Yes as suggested by Bas you can go with Automapper but along with it there is one another option is using Otis..I know Automapper is better than Otis but it can be considered as one option..
Check it out :-
http://code.google.com/p/otis-lib/
As socumented in official site :-
Otis is a .Net object transformation library, i.e. an object to object
mapper.
It automatically generates converter assemblies or classes which
convert instances of one type to instances of some other type. These
transformation can be described in type metadata using attributes, or
separately in an XML source (file, string, database)
Otis is intended to be used to solve some common design and
implementation tasks, e.g. to ease the implementation of support for
DTO classes (more here), or to convert business domain type instances
to presentation layer instances, but more generally, it can be used
anywhere where a transformation between different types is needed.
Otis removes the need to manually implement type converters.
Given that what you really want to do is serialize different parts of the object for different services, I would use Composition instead of Inheritance.
So you would have:
public Item
{
public string A;
public bool B;
public char C;
...// 20 fields
}
public AdvancedItem
{
[DataMember]
public Item baseItem;
[DataMember]
public string Z;
}
public Item(Item item)
{
A = item.A;
B = item.B;
...;//many lines
}
public AdvancedItem(Item item, string z)
{
baseItem = item; // or item.Clone();
Z = z;
}
I have a list of numbers, and I wrote a method that performs some calculations on these numbers; all in all, it's about a page of code. The method performs some arithmetic and comparisons on these numbers.
My problem is that, in one case, the list is an IList<byte>, and in another case, it's an IList<float>. The algorithm in both cases is exactly the same (yes, I'm aware of things like overflow errors and loss of precision, but in my case it works). How can I write a method that will handle both lists ? I can't write something like void DoStuff<T>(IList<T> numbers), because there are no arithmetic operators (+ - * /) that are generic.
One solution is to simply store everything as float, but I'd like to avoid it. The lists are quite long, and thus storing floats instead of bytes would cost too much memory. I could also do something like DoStuffFloat(byteList.Select(b => (float)b)), but I don't want to pay the performance penalty, either, if I can avoid it.
Short of copy-pasting the entire method and replacing "float" with "byte" (or vice versa), is there some decent solution ?
EDIT: I should've mentioned that I'm restricted to using .NET 3.5 for this project.
What you could do is create a generic interface that includes the operations that you want to support, create a generic factory to create instances for the supported types to perform the operations, and use it.
e.g.,
public interface IOperations<T>
{
T Add(T a, T b);
T Subtract(T a, T b);
T Multiply(T a, T b);
T Divide(T a, T b);
}
public static class Operations<T>
{
public static IOperations<T> Default { get { return Create(); } }
static IOperations<T> Create()
{
var type = typeof(T);
switch (Type.GetTypeCode(type))
{
case TypeCode.Byte:
return (IOperations<T>)new ByteOperations();
case TypeCode.Single:
return (IOperations<T>)new SingleOperations();
default:
var message = String.Format("Operations for type {0} is not supported.", type.Name);
throw new NotSupportedException(message);
}
}
class ByteOperations : IOperations<byte>
{
public byte Add(byte a, byte b) { return unchecked ((byte)(a + b)); }
public byte Subtract(byte a, byte b) { return unchecked ((byte)(a - b)); }
public byte Multiply(byte a, byte b) { return unchecked ((byte)(a * b)); }
public byte Divide(byte a, byte b) { return unchecked ((byte)(a / b)); }
}
class SingleOperations : IOperations<float>
{
public float Add(float a, float b) { return a + b; }
public float Subtract(float a, float b) { return a - b; }
public float Multiply(float a, float b) { return a * b; }
public float Divide(float a, float b) { return a / b; }
}
}
T Mean<T>(IList<T> numbers)
{
var operations = Operations<T>.Default;
var sum = numbers.Aggregate(operations.Add);
var count = (T)Convert.ChangeType(numbers.Count, typeof(T));
return operations.Divide(sum, count);
}
var resultByte = Mean(new byte[] { 1, 2, 3, 4 }); // 2
var resultSingle = Mean(new float[] { 1.1F, 2.1F, 3.1F, 4.1F }); // 2.6F
var resultInt = Mean(new int[] { 1, 2, 3, 4 }); // not supported
If you don't mind a small performance hit, you could dynamically create the operations needed.
class GenericOperations<T> : IOperations<T>
{
public GenericOperations()
{
add = CreateLambda(Expression.Add);
subtract = CreateLambda(Expression.Subtract);
multiply = CreateLambda(Expression.Multiply);
divide = CreateLambda(Expression.Divide);
}
private Func<T, T, T> add, subtract, multiply, divide;
private static Func<T, T, T> CreateLambda(Func<Expression, Expression, BinaryExpression> op)
{
var a = Expression.Parameter(typeof(T), "a");
var b = Expression.Parameter(typeof(T), "b");
var body = op(a, b);
var expr = Expression.Lambda<Func<T, T, T>>(body, a, b);
return expr.Compile();
}
public T Add(T a, T b) { return add(a, b); }
public T Subtract(T a, T b) { return subtract(a, b); }
public T Multiply(T a, T b) { return multiply(a, b); }
public T Divide(T a, T b) { return divide(a, b); }
}
I don't know if this is the best method for your case but it is useful for similar cases too.
This can be done by using the dynamic keyword. What dynamic will do is it will not do the compile time checks until runtime.
Here is a small sample program to show how it works.
class Program
{
static void Main()
{
List<byte> bytes = new List<byte>();
bytes.Add(2);
bytes.Add(1);
List<float> floats = new List<float>();
floats.Add(2.5F);
floats.Add(1F);
Console.WriteLine(DoStuff(bytes));
Console.WriteLine(DoStuff(floats));
Console.ReadLine();
}
static dynamic DoStuff(IList items)
{
dynamic item0 = items[0];
dynamic item1 = items[1];
return item0 - item1;
}
}
Unfortunately in my quick testing I could not make IList<dynamic> work however using the non generic IList then accessing the members as a dynamic works fine.
Create classes to wrap the underlying values, and have them each implement an interface with the operations you need. Then, use ILists of that interface instead of the raw values.