Using C# 3.0, .NET 3.5
I have a need for an enumeration that is a little smarter than a simple number. I have worked around this with static classes and properties, but one thing I am missing is the ability to use the enumeration like a bit flag without accessing a specfic properity.
For example this works:
public interface isomething
{
int value { get; }
}
public class something : isomething
{
public int value {get; private set;}
public somthing(int value)
{
this.value = value
}
public void DoSomething()
{
throw new NotImplementedException();
}
}
public static class SuperEnum
{
public static isomething first = new something(1);
public static isomething second= new something(2);
}
Then execute something like this:
Assert.IsTrue((SuperEnum.first.value | SuperEnum.second.value) == 3);
And you get a true. But if I add this to the something class:
public static int operator | (something leftSide, isomething rightside)
{
return leftside.value | rightside.value
}
Then execute something like this:
Assert.IsTrue((SuperEnum.first | SuperEnum.second) == 3);
I get a message that | operator can not used on the isomething type which sucks.
If I go with concrete types, I am fine, but that is going to cause problems in the future.
Anyone got any ideas?
Thanks, mark
I am not sure what you're trying to achieve. I think there is probably a better solution to the problem, but if the operator is important you can do it using an abstract class instead of interface:
public abstract class SomethingBase
{
protected int value;
protected SomethingBase(int value)
{
this.value = value;
}
public static int operator |(SomethingBase leftSide, SomethingBase rightside)
{
return leftSide.value | rightside.value;
}
}
public class Something : SomethingBase
{
public int Value
{
get { return value; }
}
public Something(int value) : base(value)
{
}
public void DoSomething()
{
throw new NotImplementedException();
}
}
Your issue comes from the fact that the ISomething interface doesn't declare the operator, and I'm not sure that you can make an operator a part of an interface contract. What sort of problems do you expect to be caused by using the concrete class?
If you are doing binary math, it sounds like you are talking about a value. If you are talking about a value, an immutable concrete type would be a good choice (perhaps a struct, depending on the size). And if you have a concrete type, you can add a bespoke operator.
Alternatively you could add an Or method to the interface (or add an extension method to do the same), but this may involve the first operand choosing the concrete type... but then, I'm not sure what the interface is adding anyway.
Related
Given class:
public interface ITest
{
DateTime DataIns { get; set; }
}
And given the class:
public abstract class ATest<T> where T : class, ITest
{
public void Test() {
// I would like to do this:
// var field = nameof(T.DataIns);
}
}
Is it not possible to get the nameof interface property without using the interface itself? I know that, of course, is possible to do that var field = nameof(IMetrics.DataIns); , but I would like to refer to the generics type.
Looks like it is unlikely to happen: https://github.com/dotnet/csharplang/issues/810
You can cheat a bit and go via something that generates a T symbol, since nameof is a compile-time construct. In some sense this is better than coding against the interface as it does the right thing at compilation, however that's more a matter of opinion.
public abstract class ATest<T> where T : class, ITest
{
public void Test()
{
var field = nameof(THack.DataIns);
}
static T THack => throw new NotImplementedException();
}
Considering that this can be done, it is a bit silly that you cannot use T directly.
Say, we have two classes:
public class A
{
protected static readonly int DefaultValue = 123;
int value;
public A()
{
value = DefaultValue;
}
public A(int _value)
{
value = _value;
}
}
public class B : A
{
public B(XElement x)
: base(x.Element("int") == null
? A.DefaultValue
: (int)x.Element("int"))
{
}
}
I understand that I could make a parameterless constructor for class B::
public B():base()
{
}
and have smth like this:
B objB = (x.Element("int") == null)?new B():new B((int)x.Element("int"));
but I'd love to have this logic encapsulated in class B.
Also I see I can do some kind of static factory method and have it encapsulated (and even make those class B constructors private if necessary):
public static B GetInstance(XElement x)
{
return (x.Element("int") == null)?new B():new B((int)x.Element("int"));
}
But I'd love to be able to have smth like the following pseudo code:
public class A
{
//don't need this anymore
//protected static readonly int DefaultValue = 123;
int value;
public A()
{
value = 123;
}
public A(int _value)
{
value = _value;
}
}
public class B : A
{
public B(XElement x)
: x.Element("int") == null
? base()
: base((int)x.Element("int"))
{
}
}
Or is there any other approach which could do the same thing as nice and even better?
The only condition that can change the base constructor used is the actual constructor that is called - find another approach to the problem :)
A factory method is one way, as noted. Also, I believe Ninject (and possibly other DI frameworks) allows choosing different constructors dynamically based upon argument values. Sadly, I do not have enough DI experience ..
Another possibility in this case is to take in int? which, while it does change the interface, would allow null to be easily coalesced to the default value.
Have you tried playing around with a null int (int?) in the Class A constructor? With a optional parameter you might be able get away with one constructor.
I need to create math problems. Arithmetic, Comparison 2 numbers.. every class contains similiar features like CheckTheAnswer and GenerateProblem, but each one of them receives different parameters. Here is an example what I'm trying to do.
public class Problem<T>
{
public virtual bool CheckTheAnswer()
{
return false;
}
public static T GenerateProblem()
{
return T;
}
}
public class Arithmetic : Problem<Arithmetic>
{
public bool CheckTheAnswer(decimal result)
{
...
}
public static Arithmetic GenerateProblem(Tuple<int, decimal, decimal> condition)
{
...
}
}
public class Comparison2Numbers : Problem<Comparison2Numbers>
{
public bool CheckTheAnswer(decimal result1, decimal result2)
{
...
}
public static Comparison2Numbers GenerateProblem(Tuple<decimal, decimal> condition)
{
...
}
}
I was thinking in interfaces, but I realized in interfaces can't have static functions.
Thanks in advance.
OK, the question is.. is there a way to do this?
Arithmetic a = new Arithmetic();
Problem<Arithmetic> p = a;
And get the functions from Arithmetic class. Maybe this is not the best way to generalize this problems, what do you opine?
I think this is the kind of problem where you probably want an abstract factory for your generators, rather than static methods. You can use the constructors of individual factories to pass in data with varying arguments. Each will have a fixed Create method though.
interface IProblemFactory<T> where T : IProblem<T>
{
T Create();
}
class ArithmeticProblemFactory : IProblemFactory<Arithmetic>
{
private Tuple<int, decimal, decimal> condition;
public ArithmeticProblemFactory(Tuple<int, decimal, decimal> condition) {
this.condition = conditionl
}
Arithmetic IProblemFactory<Arithmetic>.Create() {
...
}
}
To get the behavior of polymorphic creation, the abstract factor pattern would be best for this. See Mark's answer for an example of how to set this up.
But you also need the ability to check the answer with different number of arguments. From your examples, it seem that you will always expect a type of decimal for each of the arguments. Assuming this is correct, you can make CheckTheAnswer a variadic method. I might also suggest adding a polymorphic property to access the desired number of arguments. So we now have:
public abstract class Problem<T>
{
public abstract int ResultCount { get; }
public abstract bool CheckTheAnswer(params decimal[] results);
}
And the a base class could be along the lines of:
public class Arithmetic : Problem<Arithmetic>
{
public override int ResultCount
{
get
{
return 2;
}
}
public override bool CheckTheAnswer(params decimal[] results)
{
if(results.Length != ResultCount)
throw new ArgumentException("Only expected " + ResultCount + " arguments.");
...
}
}
While this doesn't provide compile-time type safety in the number of arguments, it will allow you to solve your problem using run-time guarantees.
is there some 'where' type contraints in can add to make the follwing code compile ?
public class Plus<T> : BinaryOperator<T> where T : ...
{
public override T Evaluate(IContext<T> context)
{
return left.Evaluate(context) + right.Evaluate(context);
}
}
Thanks :)
There are no such devices in C#. A few options are available, though:
in C# 4.0 and .NET 4.0 (or above), use dynamic, which supports + but offers no compile time checking
in .NET 3.5 (or above), MiscUtil offers an Operator class which makes operators available as methods - again, without any compile-time checking
So either:
return (dynamic)left.Evaluate(context) + (dynamic)right.Evaluate(context);
or
return Operator.Add(left.Evaluate(context), right.Evaluate(context));
The Type parameter constraints in C# are very limited and is listed here. So the answer is no as far as compile time check goes.
If T is a type that you create and manage, one way to go about it would be to
interface IAddable
{
IAddable Add(IAddable foo);
}
and implement IFoo for all your types and use where T: IAddable as constraint and use Add() instead of +
In C# 11 and .NET 7, there is a feature exactly for this (see Microsoft Docs). It would have to go as follow:
public interface IAddable<T> where T : IAddable<T>
{
static abstract T operator +(T left, T right);
}
public class Foo : IAddable<Foo>
{
public static Foo operator +(Foo left, Foo right)
{
/* Something */
}
}
With C# 8 default interface methods you can achieve something similar, but it might not solve your exact use case:
You can define an interface with a default implementation of an operator:
public interface IFoo
{
double Value { get; }
public static IFoo operator +(IFoo a, IFoo b)
{
return new Foo(a.Value + b.Value);
}
}
public class Foo : IFoo
{
public double Value { get; }
public Foo(double value)
{
Value = value;
}
}
And consume it in a generic method/class like this:
public static class Program
{
public static void Main()
{
var f1 = new Foo(1);
var f2 = new Foo(2);
var sum = Add(f1, f2);
Console.WriteLine(sum.Value);
}
public static IFoo Add<T>(T a, T b) where T : IFoo
{
return a + b;
}
}
Using a generic constraints you can force T
to be a reference type or a value type
to inherit from a certain class
to implement certain interface
to have parameterless constructor
But that's all. You can't force the existence of the static operator+ on it.
I'm looking for some way to effectively hide inherited members. I have a library of classes which inherit from common base classes. Some of the more recent descendant classes inherit dependency properties which have become vestigial and can be a little confusing when using IntelliSense or using the classes in a visual designer.
These classes are all controls that are written to be compiled for either WPF or Silverlight 2.0. I know about ICustomTypeDescriptor and ICustomPropertyProvider, but I'm pretty certain those can't be used in Silverlight.
It's not as much a functional issue as a usability issue. What should I do?
Update
Some of the properties that I would really like to hide come from ancestors that are not my own and because of a specific tool I'm designing for, I can't do member hiding with the new operator. (I know, it's ridiculous)
Override them like Michael Suggests above and to prevent folks from using the overridden (sp?) methods, mark them as obsolete:
[Obsolete("These are not supported in this class.", true)]
public override void dontcallmeanymore()
{
}
If the second parm is set to true, a compiler error will be generated if anyone tries to call that method and the string in the first parm is the message. If parm2 is false only a compiler warning will be generated.
While you cannot prevent usage of those inherited members to my knowledge, you should be able to hide them from IntelliSense using the EditorBrowsableAttribute:
Using System.ComponentModel;
[EditorBrowsable(EditorBrowsableState.Never)]
private string MyHiddenString = "Muahahahahahahahaha";
Edit: Just saw this in the documentation comments, which makes it kinda useless for this purpose:
There is a prominent note that states that this attribute "does not suppress members from a class in the same assembly". That is true but not complete. Actually, the attribute does not suppress members from a class in the same solution.
One potential thing you can do is contain the object rather than extend from the other class. This will give you the most flexibility in terms of exposing what you want to expose, but if you absolutely need the object to be of that type it is not the ideal solution (however you could expose the object from a getter).
Thus:
public class MyClass : BaseClass
{
// Your stuff here
}
Becomes:
public class MyClass
{
private BaseClass baseClass;
public void ExposeThisMethod()
{
baseClass.ExposeThisMethod();
}
}
Or:
public class MyClass
{
private BaseClass baseClass;
public BaseClass BaseClass
{
get
{
return baseClass;
}
}
}
I think you're best least hackish way is to consider composition as opposed to inheritance.
Or, you could create an interface that has the members you want, have your derived class implement that interface, and program against the interface.
I know there's been several answers to this, and it's quite old now, but the simplest method to do this is just declare them as new private.
Consider an example I am currently working on, where I have an API that makes available every method in a 3rd party DLL. I have to take their methods, but I want to use a .Net property, instead of a "getThisValue" and "setThisValue" method. So, I build a second class, inherit the first, make a property that uses the get and set methods, and then override the original get and set methods as private. They're still available to anyone wanting to build something different on them, but if they just want to use the engine I'm building, then they'll be able to use properties instead of methods.
Using the double class method gets rid of any restrictions on being unable to use the new declaration to hide the members. You simply can't use override if the members are marked as virtual.
public class APIClass
{
private static const string DllName = "external.dll";
[DllImport(DllName)]
public extern unsafe uint external_setSomething(int x, uint y);
[DllImport(DllName)]
public extern unsafe uint external_getSomething(int x, uint* y);
public enum valueEnum
{
On = 0x01000000;
Off = 0x00000000;
OnWithOptions = 0x01010000;
OffWithOptions = 0x00010000;
}
}
public class APIUsageClass : APIClass
{
public int Identifier;
private APIClass m_internalInstance = new APIClass();
public valueEnum Something
{
get
{
unsafe
{
valueEnum y;
fixed (valueEnum* yPtr = &y)
{
m_internalInstance.external_getSomething(Identifier, yPtr);
}
return y;
}
}
set
{
m_internalInstance.external_setSomething(Identifier, value);
}
}
new private uint external_setSomething(int x, float y) { return 0; }
new private unsafe uint external_getSomething(int x, float* y) { return 0; }
}
Now valueEnum is available to both classes, but only the property is visible in the APIUsageClass class. The APIClass class is still available for people who want to extend the original API or use it in a different way, and the APIUsageClass is available for those who want something more simple.
Ultimately, what I'll be doing is making the APIClass internal, and only expose my inherited class.
To fully hide and mark not to use, including intellisense which I believe is what most readers expect
[Obsolete("Not applicable in this class.")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
I tested all of the proposed solutions and they do not really hide new members.
But this one DOES:
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new string MyHiddenProperty
{
get { return _myHiddenProperty; }
}
But in code-behide it's still accessible, so add as well Obsolete Attribute
[Obsolete("This property is not supported in this class", true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new string MyHiddenProperty
{
get { return _myHiddenProperty; }
}
While clearly stated above that it is not possible in C# to change the access modifiers on inherited methods and properties, I overcame this issue through a sort of "fake inheritance" using implicit casting.
Example:
public class A
{
int var1;
int var2;
public A(int var1, int var2)
{
this.var1 = var1;
this.var2 = var2;
}
public void Method1(int i)
{
var1 = i;
}
public int Method2()
{
return var1+var2;
}
}
Now lets say you want a class B to inherit from class A, but want to change some accessibility or even change Method1 entirely
public class B
{
private A parent;
public B(int var1, int var2)
{
parent = new A(var1, var2);
}
int var1
{
get {return this.parent.var1;}
}
int var2
{
get {return this.parent.var2;}
set {this.parent.var2 = value;}
}
public Method1(int i)
{
this.parent.Method1(i*i);
}
private Method2()
{
this.parent.Method2();
}
public static implicit operator A(B b)
{
return b.parent;
}
}
By including the implicit cast at the end, it allows us to treat B objects as As when we need to. It can also be useful to define an implicit cast from A->B.
The biggest flaw to this approach is that you need to re-write every method/property that you intend to "inherit".
There's probably even more flaws to this approach, but I like to use it as a sort of "fake inheritance".
Note:
While this allows for changing the accessibility of public properties, it doesn't solve the issue of making protected properties public.
You can use an interface
public static void Main()
{
NoRemoveList<string> testList = ListFactory<string>.NewList();
testList.Add(" this is ok ");
// not ok
//testList.RemoveAt(0);
}
public interface NoRemoveList<T>
{
T this[int index] { get; }
int Count { get; }
void Add(T item);
}
public class ListFactory<T>
{
private class HiddenList: List<T>, NoRemoveList<T>
{
// no access outside
}
public static NoRemoveList<T> NewList()
{
return new HiddenList();
}
}