Can't call overriden toSting() - c#

I just start with c#.
I want to override toString() method with parameter. i do:
public string ToString(bool param)
{
if (param)
{
return string.Format(FIO);
}
else
{
return string.Format(Address);
}
}
And call it:
myClass.toString(true);
But get error:
method toString() has 0 parameters but invoked with 1 argument.
Whats can be wrong?

Given this class:
class MyClass
{
public string ToString(bool param)
{
return param.ToString();
}
}
This code will work as expected:
MyClass myClass = new MyClass();
string s = myClass.ToString(true);
Therefore you have an error in part of the code that you are not showing us.
Possibilities:
Typo in the method name?
Using the wrong class?

C# is case sensitive. Your method is "ToString", but you are calling "toString"
change
myClass.toString(true);
to
myClass.ToString(true); // <-- capital T

to override - you need to use the override keyword. However, you cannot override the default ToString() method since it is parameterless so you cannot "modify" it to add a parameter thus you need to create another method.
but your example does not work anyway. C# is case sensitive so you need to call:
myClass.ToString(true)
NOT:
myClass.toString(true)

The Error is telling you exactly what is wrong.
When overriding a method (where you missed the "override") keyword you have to keep the parameters. So you can overwrite .ToString(), but not .ToString(bool something)
As you surely want to achive something completely different than the .ToString()-Method I would simply advice to write a complete own method instead of overwriting
My Suggestion would be:
public override string ToString() {
return string.Format(Address);
}
public string ToStringParam() {
return string.format(FIO);
}

I think you are using the wrong ToString from the base class. For a reason the complier does not find the correct to string; Maybe you are casting somewhere the object.
For this problem; I recommend you to use the Extension Methods:
namespace ExtensionMethods
{
public static class MyExtensions
{
// I DONOT KNOW YOUR OBJECT TYPE I JUST HAVE USED A DUMMY THING; YOU CAN REPLACE IT!!!!
public static string ToString(this MyType myClass, bool param)
{
if (param)
{
return string.Format(myClass.FIO);
}
return string.Format(myClass.Address);
}
}
}

Related

Extend "object" with a null check more readable than ReferenceEquals

I tried to extend "object" to allow a more readable check if an object is null.
Now, object.ReferenceEquals really checks for a null object, (the rare times it will not apply are since the operator == can be overridden. the object.Equals(null) method can also be overridden).
But the object.ReferenceEquals(null, obj); is not too readable is it?... So, I thought, why not write an extension method to the System.object that will provide that check using object.IsNull(obj);
I've tried:
public static class MyExtClass
{
// the "IsNull" extension to "object"
public static bool IsNull(this object obj)
{
return object.ReferenceEquals(obj, null);
}
}
public SomeOtherClass
{
public static void TryUsingTheExtension()
{
object obj;
// Why does this line fail? the extension method is not recognized
// I get: 'object' does not contain a definition for "IsNull"
bool itIsANull = object.IsNull(obj);
}
}
What did I miss?
Extension methods can be invoked only on instance and not on a class that they extend. So this line of code bool itIsANull = object.IsNull(obj); is incorrect because object is type and not an instance. Change it to :
bool itIsANull = (new object()).IsNull();
Or you can call it on class MyExtClass but not on object class (which is located in mscore.lib) :
MyExtClass.IsNull(new object());
P.S.
It looks like you missed something about extension methods. The truth is that they have nothing to do with classes that they extend. It's just a convenience that is provided for us by Intellisense with use of reflection.
Object class is located in mscorelib and is immutable. You can't add something to it. But what really happens is that Intellisense searches for all public methods that are located in public static classes and accept first argument with keyword 'this' as parameter. If one is found it's 'mapped' to the class that it extends. So when we type obj.MyExtMethod() on instance of that class it is automatically converted by compiler to Helper.MyExtMethod(obj); (if helper is our static class);
Try
bool itIsANull = obj.IsNull();
You wrote an extension method, and extension methods exist in a different type but extend objects of the specified type by another method.
But when you call object.IsNull(), then you are looking for a static method that exists on the object type.
Instead, you have two ways to call your method:
// either the static method on the class
MyExtClass.IsNull(obj);
// or using the actual feature of extension methods
obj.isNull();
Because it’s an extension method, the latter form will be automatically converted into the former at compile time.
You are calling the extension method on the object itself. You should call the methd on the instance instead -
bool itIsANull = obj.IsNull()
Try:
class Program
{
static void Main(string[] args)
{
var o = new object();
if (o.IsNull())
{
Console.Write("null");
}
}
}
public static class Request
{
public static bool IsNull(this object obj)
{
return ReferenceEquals(obj, null);
}
}
public static class MyExtClass
{
// the "IsNull" extension to "object"
public static bool IsNull(this object obj)
{
return object.ReferenceEquals(obj, null);
}
}
public class SomeOtherClass
{
public static void TryUsingTheExtension()
{
object obj =null;
bool itIsANull = obj.IsNull();
}
}

How to Extend the Type Class

this is my code:
bool ch=Type.IsBuiltIn("System.Int32"); // not working-> syntax error
public static class MyExtentions
{
public static bool IsBuiltIn(this Type t, string _type)
{
return (Type.GetType(_type) == null) ? false : true;
}
}
Please I want Extend Type Class by IsBuiltIn new method
You can't have static extension methods. Your extension method works on an instance of the Type class, so to call it you'd have to do something like this:
typeof(Type).IsBuiltIn("System.Int32")
The workaround for this is to just put your extension method in a utility class, e.g. like the following, and call it like a normal static function:
public static class TypeExt
{
public static bool IsBuiltIn(string _type)
{
return Type.GetType(_type) == null;
}
}
// To call it:
TypeExt.IsBuiltIn("System.Int32")
By the way, I don't think this will tell you whether the type is "built-in"; it will merely tell you whether a type with the given name has been loaded into the process.
Extension methods are intended to describe new APIs on instances, not types. In your case, that API would be something like:
Type someType = typeof(string); // for example
bool isBuiltIn = someType.IsBuiltIn("Some.Other.Type");
which... clearly isn't what you wanted; the type here adds nothing and is not related to the IsBuiltIn. There is no compiler trick for adding new static methods to existing types, basically - so you will not be able to use Type.IsBuiltIn("Some.Other.Type").
You can't extend the Type class. You need an instance of the class to create an extension method.
Edit:
See here and here.

How to detect current type has "ToString" overrided method or not? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to determine if the MethodInfo is an override of the base method
Normally, when we execute "ToString" method of any complex type it will return current type name like the following string except there is "ToString" overrided method.
System.Data.Entity.DynamicProxies.UserRole_D77A004638495805D68478322DF47F48540438D82DC9A5A0E1B0B2A181E4A100
I want some logic to detect current type about this because I try to export data to excel format. But some property of model is complex type that doesn't define "ToString" method. Output of this property is useless for normal user.
Thanks,
You can check the DeclaringType on the methodInfo of to string
if (methodInfo.DeclaringType != typeof(YourObject)) {
...
}
system.reflection.methodinfo
You can of course do this with reflection. An alternative approach that might give you what you want and doesn't use reflection is:
if (this.ToString() != this.GetType().ToString())
{
// This Type or one of its base types has overridden object.ToString()
}
Note that you probably want to check if the current type or any base type (except object) has overridden ToString(). As a contrived example all types derived from Exception return a sensible value from ToString() (exception details including stack trace), but not all override Exception.ToString().
I think this approach to check whether particular type overrides ToString or not is a little bit brittle. We can solve this in several other ways.
First of all if string representation is required you can add additional mixin interface like IObjectDescriptor with one method: string GetDescription. And you can require this implentation from every type (and if class is not implements it throw an exception).
Second approach (if we don't want to change existing code base) is use separate helper class that will have one method: ConvertToString:
static class ToStringHelper
{
// We can use Generic method to prevent boxing
public string ConvertToString(object o)
{
var sb = new StringBuilder();
// using reflection to access all public properties, for example
return sb.ToString();
}
}
In both cases your intention and "contract" between you and your clients would be much more clear. In first case you'll throw an exception if type is not implements particular interface, with second approach you'll get at least consistent behavior.
You can use IsSubclassOf object and DeclaringType of method.
public class BaseClass
{
public string Name;
public virtual void Write(string val)
{
}
}
public class SubClass : BaseClass
{
public string Address;
public override void Write(string val)
{
base.Write(val);
}
}
Test code:
Type objType = obj.GetType();
MethodInfo info = objType.GetMethod("Write");
if (objType.IsSubclassOf(info.DeclaringType))
{
Console.WriteLine("Not Override");
}
else
Console.WriteLine("Override");

Get name of class in C#

I need to get the name of the class that I am currently in. The problem is that I am in a static property. Any idea how I can do this without a reference to this?
If you really want it, although as TomTom points out, you might not need it:
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name
System.Reflection.MethodInfo.GetCurrentMethod().DeclaringType.Name
If you are in a static property, you should be able to make the type name a constant.
If you have a static property in a base class that is inherited, and you are trying to determine the type of the child class that you are in, you can't do this with a static property. The reason is that the static property is associated with the base class type, not any base class instance. Use a regular property instead, and use GetType().Name or similar.
The following call should give you the name of the current type...
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name
You can use something like:
public static class MyClass
{
public static string FullName
{
get { return typeof(MyClass).FullName; }
}
}
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.ToString()
Which is mentioned over and over again, can be wrong if the Type is generic. It will not figure out the generic type.
class Generic<T>
{
public static string ClassName
{
[MethodImpl(MethodImplOptions.NoInlining)]
get
{
return System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.ToString();
}
}
}
Also if you don't use the NoInlining directive your code maybe inlined into the callsite which will definitely not yield the results you are after.
The following code will print Generic``1[T], rather than the particular instantiation it's being called from.
The solution is fairly obvious just use MakeGenericMethod with T to get the right instance.
The solution is fairly obvious just use MakeGenericMethod with T to get the right instance.
But if you want to know the name of T you cannot use the MakeGenericMethod. Another solution is to add a static class with a generic method:
public static class Helper
{
public static string GetName<T>()
{
Type type = typeof(T);
Type[] genericArguments = type.GetGenericArguments();
return string.Format("{0}<{1}>", type.Name, string.Join(",", genericArguments.Select(arg => arg.Name)));
}
}
No change the property ClassName to
public static string ClassName
{
get
{
return Helper.GetName<Generic<T>>();
}
}
then you will get the correct generic name, for example a call to Generic<DateTime>.ClassName will return
"Generic`1<DateTime>".

Calling a static method on a generic type parameter

I was hoping to do something like this, but it appears to be illegal in C#:
public Collection MethodThatFetchesSomething<T>()
where T : SomeBaseClass
{
return T.StaticMethodOnSomeBaseClassThatReturnsCollection();
}
I get a compile-time error:
'T' is a 'type parameter', which is not valid in the given context.
Given a generic type parameter, how can I call a static method on the generic class? The static method has to be available, given the constraint.
In this case you should just call the static method on the constrainted type directly. C# (and the CLR) do not support virtual static methods. So:
T.StaticMethodOnSomeBaseClassThatReturnsCollection
...can be no different than:
SomeBaseClass.StaticMethodOnSomeBaseClassThatReturnsCollection
Going through the generic type parameter is an unneeded indirection and hence not supported.
To elaborate on a previous answer, I think reflection is closer to what you want here. I could give 1001 reasons why you should or should not do something, I'll just answer your question as asked. I think you should call the GetMethod method on the type of the generic parameter and go from there. For example, for a function:
public void doSomething<T>() where T : someParent
{
List<T> items=(List<T>)typeof(T).GetMethod("fetchAll").Invoke(null,new object[]{});
//do something with items
}
Where T is any class that has the static method fetchAll().
Yes, I'm aware this is horrifically slow and may crash if someParent doesn't force all of its child classes to implement fetchAll but it answers the question as asked.
You can do what I call a surrogate singleton, I've been using it as a sort of "static inheritance" for a while
interface IFoo<T> where T : IFoo<T>, new()
{
ICollection<T> ReturnsCollection();
}
static class Foo<T> where T : IFoo<T>, new()
{
private static readonly T value = new();
public static ICollection<T> ReturnsCollection() => value.ReturnsCollection();
}
// Use case
public ICollection<T> DoSomething<T>() where T : IFoo<T>, new()
{
return Foo<T>.ReturnsCollection();
}
The only way of calling such a method would be via reflection, However, it sounds like it might be possible to wrap that functionality in an interface and use an instance-based IoC / factory / etc pattern.
It sounds like you're trying to use generics to work around the fact that there are no "virtual static methods" in C#.
Unfortunately, that's not gonna work.
I just wanted to throw it out there that sometimes delegates solve these problems, depending on context.
If you need to call the static method as some kind of a factory or initialization method, then you could declare a delegate and pass the static method to the relevant generic factory or whatever it is that needs this "generic class with this static method".
For example:
class Factory<TProduct> where TProduct : new()
{
public delegate void ProductInitializationMethod(TProduct newProduct);
private ProductInitializationMethod m_ProductInitializationMethod;
public Factory(ProductInitializationMethod p_ProductInitializationMethod)
{
m_ProductInitializationMethod = p_ProductInitializationMethod;
}
public TProduct CreateProduct()
{
var prod = new TProduct();
m_ProductInitializationMethod(prod);
return prod;
}
}
class ProductA
{
public static void InitializeProduct(ProductA newProduct)
{
// .. Do something with a new ProductA
}
}
class ProductB
{
public static void InitializeProduct(ProductB newProduct)
{
// .. Do something with a new ProductA
}
}
class GenericAndDelegateTest
{
public static void Main()
{
var factoryA = new Factory<ProductA>(ProductA.InitializeProduct);
var factoryB = new Factory<ProductB>(ProductB.InitializeProduct);
ProductA prodA = factoryA.CreateProduct();
ProductB prodB = factoryB.CreateProduct();
}
}
Unfortunately you can't enforce that the class has the right method, but you can at least compile-time-enforce that the resulting factory method has everything it expects (i.e an initialization method with exactly the right signature). This is better than a run time reflection exception.
This approach also has some benefits, i.e you can reuse init methods, have them be instance methods, etc.
You should be able to do this using reflection, as is described here
Due to link being dead, I found the relevant details in the wayback machine:
Assume you have a class with a static generic method:
class ClassWithGenericStaticMethod
{
public static void PrintName<T>(string prefix) where T : class
{
Console.WriteLine(prefix + " " + typeof(T).FullName);
}
}
How can you invoke this method using relection?
It turns out to be very easy… This is how you Invoke a Static Generic
Method using Reflection:
// Grabbing the type that has the static generic method
Type typeofClassWithGenericStaticMethod = typeof(ClassWithGenericStaticMethod);
// Grabbing the specific static method
MethodInfo methodInfo = typeofClassWithGenericStaticMethod.GetMethod("PrintName", System.Reflection.BindingFlags.Static | BindingFlags.Public);
// Binding the method info to generic arguments
Type[] genericArguments = new Type[] { typeof(Program) };
MethodInfo genericMethodInfo = methodInfo.MakeGenericMethod(genericArguments);
// Simply invoking the method and passing parameters
// The null parameter is the object to call the method from. Since the method is
// static, pass null.
object returnValue = genericMethodInfo.Invoke(null, new object[] { "hello" });
As of now, you can't. You need a way of telling the compiler that T has that method, and presently, there's no way to do that. (Many are pushing Microsoft to expand what can be specified in a generic constraint, so maybe this will be possible in the future).
Here, i post an example that work, it's a workaround
public interface eInterface {
void MethodOnSomeBaseClassThatReturnsCollection();
}
public T:SomeBaseClass, eInterface {
public void MethodOnSomeBaseClassThatReturnsCollection()
{ StaticMethodOnSomeBaseClassThatReturnsCollection() }
}
public Collection MethodThatFetchesSomething<T>() where T : SomeBaseClass, eInterface
{
return ((eInterface)(new T()).StaticMethodOnSomeBaseClassThatReturnsCollection();
}

Categories

Resources